数据结构是计算机中存储、组织数据的方式。通常情况下,精心选择的数据结构可以带来最优效率的算法。——《中文维基百科》
数据结构是相互之间存在的一种或多种特定关系的数据元素的集合。——《数据结构(清华大学出版社)》
数据结构的形式定义:一个二元组
Data_Structure = (D,S) 其中:D是数据元素的有限集,S是D上关系的有限集。
注意:解决问题的方法效率,跟数据的组织方式有关。
注意:解决问题的方法效率,跟算法的巧妙程度有关。
拓展:在计算机中表示信息的最小单位是二进制数的一位,叫做位(bit);在计算机中我们使用一个由若干位组合起来形成的一个位串表示一个数据元素(如用8位二进制数表示一个字符),通常称这个位串为元素或者结点。当数据元素由若干数据项组成时,位串中对应与各个数据项的子位串称为数据域。因此,元素或者结点可看成是数据元素在计算机中的映像。
根据图片加深基本概念理解:)
数据元素之间的关系在计算机中有两种不同的表示方法:顺序映像和非顺序映像,并由此得到两种不同的存储结构:顺序存储结构和链式存储结构。
顺序映像特点:借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系;
非顺序映像特点:借助只是元素存储地址的指针(pointer)表示数据元素之间的逻辑关系。
注意:数据的逻辑结构和物理结构是密切相关的两个方面,任何一个算法的设计取决于选定的数据(逻辑)结构,而算法的实现依赖于采用的存储结构。
数据类型(data type):与数据结构密切相关的一个概念,指一个值的集合和定义在这个值集上的一组操作的总称。(例如:C语言中的整型变量,其值集为某个区间上的整数,定义在其上的操作为加、减、乘、除和取模等算数运算)
抽象数据类型(Abstract Data Type简称ADT):指一个数学模型以及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关,即不论其内部结构如何改变,只要它的数学特性不变,都不影响其外部的使用。
拓展:抽象数据类型和数据类型实际上是一个概念。例如:各个计算机都拥有的“整数”类型是一个抽象数据类型,尽管它们在不同处理器上实现的方法不同,但是由于定义的数学特性相同,在用户看来都是相同的。因此,“抽象”的意义在于数据类型的数学抽象特性。
抽象数据类型按照其值的不同特性可分为三种:
原子类型
固定聚合类型
可变聚合类型
显然,后两种可称为结构类型。
抽象数据类型可用三元组表示:(D,S,P)
其中,D是数据对象,S是D上的关系集,P是对D的基本操作集。
例:
ADT Triplet{
数据对象:D={e1,e2,e3|e1,e2,e3属于ElemSet(定义了关系运算的某个集合)
数据关系;R1={<e1,e2>,<e2,e3>}
基本操作:
InitTriplet(&t,v1,v2,v3)
操作结果:构造了三元组T,元素e1,e2和e3分别被赋以参数v1,v2和v3的值。
DestroyTriplet(&T)
操作结果:三元组T被销毁
Get(T,i,&e)
初始条件:三元组T已存在,1<=i<=3
操作结果:用e返回T的第i元的值
put(&T,i,e,)
初始条件:三元组T已存在,1<=i<=3
操作结果:改变T的第i元的值为e
IsAscending(T)
初始条件:三元组T已存在
操作结果:如果T的3个元素按升序排列,则返回1,否则返回0
IsDescending(T)
初始条件:三元组T已存在。
操作结果:如果T的3个元素按降序排列,则返回1,否则返回0.
Max(T,&e)
初始条件:三元组T已存在
操作结果:用e返回T的三个元素中的最大值
Min(T,&e)
初始条件:三元组T已存在
操作结果:用e返回T的三个元素中的最小值
}ADT Triplet
void SelectionSort(int List[],int N)
{/*将N个整数List[0]...List[N-1]进行非递减排序*/
for(int i = 0;i < N,i++){
MinPosition = ScanForMin(List,i,N-1);
/*从List[i]到List[N-1]中找最小元,并将其位置赋给MinPosition*/
Swap(List[i],List[MinPosition]);
/*将未排序部分的最小元换到有序部分的最后位置*/
}
}
for(i = 1;i <= n,++i){
for(j = 1;j <=n;++j){
c[i][j] = 0;
for(k = 1;k <= n;++k)
c[i][j] += a[i][k]*b[k][j];
}
}
复杂度函数图像表示:
复杂度分析技巧:
应用实例:
给定N个整数序列{A1,A2...AN},求函数f(i,j),f(i,j)是指该序列中和最大的子序列之和。
算法1:
int MaxSubseqSum1(int A[],int N)
{ int ThisSum,MaxSun = 0;
int i,j,k;
for(i = 0;i < N;i++){/*i是子列左端位置元素*/
for(j = i;j < N;j++){/*j是子列右端位置元素*/
ThisSum = 0;/*ThisSum是从A[i]到A[j]的子列和*/
for(k = i;k <= j;k++)
ThisSum += A[k];
if(ThisSum > MaxSum)/*判断刚得到的子列和是否更大*/
MaxSum = ThisSum;/*如果条件成立,则更新结果*/
}/*j循环结束*/
}/*i循环结束*/
return MaxSum;
}
不难分析,有三重嵌套循环,故T(n)=O(N^3);
算法2:
int MaxSubseqSum1(int A[],int N)
{ int ThisSum,MaxSun = 0;
int i,j;
for(i = 0;i < N;i++){/*i是子列左端位置元素*/
ThisSum = 0;/*ThisSum是从A[i]到A[j]的子列和*/
for(j = i;j < N;j++){/*j是子列右端位置元素*/
ThisSum += A[j];
/*对于相同的i,不同的j,只要在j-1次循环的基础上累加一项即可*/
if(ThisSum > MaxSum)/*判断刚得到的子列和是否更大*/
MaxSum = ThisSum;/*如果条件成立,则更新结果*/
}/*j循环结束*/
}/*i循环结束*/
return MaxSum;
}
算法2在算法1基础上进行改进,T(n)=O(N^2);
算法3:分而治之
算法4:在线处理(在线的意思是指每输入一个数据就进行即时处理,在任何一个地方终止输入,算法都能够正确给出当前解)
int MaxSubseqSum4(int A[],int N)
{ int ThisSum,MaxSum;
int i;
ThisSum = MaxSum = 0;
for(i = 0;i < N;i++){
ThisSum += A[i];/*向右累加*/
if(ThisSum > MaxSum)
MaxSum = ThisSum;/*发现更大子列和则更新当前结果*/
else if(ThisSum < 0)/*如果当前子列和为负*/
ThisSum = 0;/*则不可能使后面的部分和增大,抛弃之*/*********************重点************************
}
return MaxSum;
}
其算法复杂度为T(n)=O(N)(最快的算法)。
原文:https://www.cnblogs.com/masterYHH/p/14079073.html