内容: 主要介绍数据结构及算法的基础知识,一些基本的概念和术语,以及算法的定义、算法的特性、算法的时间复杂度和空间复杂度
注: 该系列下的数据结构及算法的代码主要采用C语言的语法,但是因为要使用到C++的一些特性(引用类型和bool类型),代码均将存为cpp源文件!
1. 数据结构: 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。 ----来自百度百科
2.基本概念和术语:
数据: 是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称 比如: 整数和实数,字符串, 图形, 图像, 动画
数据元素: 是数据的基本单位,在计算机程序中作为一个整体进行考虑和处理。比如说链表中的一个节点可以称为一个数据元素。 一个数据元素可以由若干个数据项组成,比如一本书的书名信息作为一个数据元素,而书目信息中的每一项(书名,作者,出版社)为一个数据项。数据项是数据的不可分割的最小单位
数据对象: 是性质相同的数据元素的集合,是数据的一个子集 eg: 整数数据对象,字母字符数据对象
数据结构: 相互之间存在一种或多种特定关系的数据元素的集合,数据元素之间的相互关系称为结构
3.数据结构中的逻辑结构和存储结构:
逻辑结构: 数据的逻辑结构是从逻辑上描述数据结构,与数据的存储无关,是独立于计算机的,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型
逻辑结构的分类:
(1)集合结构:数据元素之间除了属于同一集合的关系外无其他关系
(2)线性结构:数据元素之间存在一对一的关系,eg:单链表结构中第一个节点中有一个指针指向下一个节点,第一个节点和下一个节点之间是一对一的关系
(3)树结构: 数据元素之间存在一对多的关系, eg:在公司的管理体系中,总经理管理多名经理,而一名经理管理多名员工
(4)图结构或网结构:数据元素之间存在多对多的关系, eg:多位同学之间的朋友关系,任何两位同学都可以是朋友,从而构成图结构或网结构
注:集合结构、树结构、图结构和网结构都属于非线性结构
线性结构的具体数据结构:线性表(顺序表、单链表),栈和队列,字符串;非线性结构的具体数据结构:树、二叉树、有向图、无向图。我将在这个专题的后面继续详细介绍这些结构的定义和实现。
存储结构:数据对象在计算机中的存储表示称为数据的存储结构,数据元素在计算机中有两种基本的存储结构,分别是顺序存储结构和链式存储结构。
顺序存储结构:把逻辑上相邻的结点存储在物理位置相邻的存储单元里,结点间的逻辑关系由存储单元的邻接关系来体现,由此得到的存储表示称为顺序存储结构 ----来自百度百科,也就是说顺序存储结构存储的数据元素在计算机中的存储位置是相邻的,顺序存储结构经常借用数组来实现。比如说线性表中的顺序表就是顺序存储结构。
链式存储结构:不要求逻辑上相邻的结点在物理位置上也相邻,结点间的逻辑关系是由附加的指针字段表示的。由此得到的存储表示称为链式存储结构----来自百度百科, 也就是说链式存储结构在计算机中的存储位置不一定相邻,他们只是在逻辑关系上相邻,链式存储结构常常使用指针来实现。比如说线性表中的单链表就是链式存储结构。
4.算法: 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。----来自百度百科
5. 算法的特性:算法有五大特性,分别是有穷性、确定性、可行性、输入、输出,任何一个算法都要具有这五个特性。
有穷性: 算法总在执行一定的步数后结束,且每一步都必须在一定的时间以内完成。也就是说算法不能永远执行,永不结束。
确定性: 算法的每一步的含义必须明确,不能有二义性
可行性: 算法的所有操作都可以通过已经实现的基本操作运算执行有限次数实现。
输入: 一个算法应该有0个或多个输入。0个输入时,算法的输入在算法中已明确存在,不需要外界的参与,比如一个a+b的算法,在算法里就固定a的值为1,b的值为2;多个输入时,当用函数描述算法时,算法的输入为函数的参数 。
输出: 一个算法应该有一个或多个输出,输出是算法加工的结果。当用函数描述算法时,输出一般用返回值或引用类型的形参表示。
6.算法的评价: 算法的评价从以下4方面评价: 正确性, 可读性, 健壮性, 高效性
正确性: 在合理的数据输入下能在有效的时间内得到正确的结果。
可读性: 算法的思想易于他人理解和掌握。
健壮性: 对非法的数据有较好的处理和反应。
高效性: 高效性主要体现在时间和空间上,时间高效是指算法设计合理,执行效率高,可用时间复杂度来衡量;空间高效是指算法占用的存储空间合理,可以用空间复杂度来衡量。
7.算法的时间复杂度和空间复杂度:
时间复杂度:算法的时间复杂度是指执行算法所需要的计算工作量。一般来说,计算机算法是问题规模n 的函数f(n),算法的时间复杂度也因此记做T(n)=Ο(f(n))。----来自百度百科
常见的复杂度(复杂度由低到高):
(1)常量阶:O(1) (2)对数阶:O(logn) (3)线性阶:O(n) (4)线性对数阶:O(nlogn) (5)平方阶:O(n^2) (6)立方阶:O(n^3)
一个算法是由多条以上的语句构成的,算法的最终时间复杂度一般是指这些语句中的最坏复杂度(也就是复杂度最高的)。
空间复杂度:算法的空间复杂度是指算法需要消耗的内存空间。其计算和表示方法与时间复杂度类似,一般都用复杂度的渐近性来表示,空间复杂度记为S(n)=O(f(n))。同时间复杂度相比,空间复杂度的分析要简单得多。----来自百度百科
常见算法的空间复杂度:
for(int i=0;i<n/2;i++)
{
temp = a[i];
a[i] = a[n-i-1];
a[n-i-1] = t;
}
上述算法是将一个一维数组a中的n个数逆序存放到原数组中,明显该算法只用到了一个额外的变量temp,与问题规模大小n无关,其空间复杂度为O(1)
for(i=0;i<n;i++)
b[i] = a[n-i-1];
for(i=0;i<n;i++)
a[i] = b[i];
上述算法借用了另一个大小为n的数组b,其时间复杂度为O(n)