数据结构没有官方统一定义
- "数据结构是数据对象,以及存在于该对象的实例和组成实例的数据元素之间的各种联系.这种联系可以通过定义相关的函数来给出." Sartaj Sahni <<数据结构,算法与应用>>
- "数据结构是计算机中存储,组织数据的方式.通常情况下,精心选择的数据结构可以带来最有效率的算法." 中文维基百科
- "数据结构是ADT(抽象数据类型Abstract Data Type)的数据实现." Clifford A.Shaffer,<<数据结构与算法分析>>
关于数据组织
如何在书架上摆放图书?(换言之,给了你一堆数据,又给了你一些空间,你要怎么把数据存起来呢?)
不同类型(大小)的书架,来摆放图书当然不同.所有说:数据怎么组织,其实跟这个数据的规模有关系.
图书的摆放要使得2个相关操作方便实现:
操作1,新书怎么插入?
操作2,怎么找到某本指定的图书?
法一:随便放
操作一实现:哪里有空插哪里
操作二实现:当图书规模过大时,一本一本找,显然不可取
法二:按照书名的拼音字母排放
操作一实现:二分查找找到位置后,进行一本一本错位,当然图书规模过大时,同样不可取
操作二实现:二分查找
法三:把书架按类型划分区域,书本分类型摆放,每类再按照书名的拼音字母排放
不管在那个类里做什么操作,这个图书的规模都小了很多.
操作一实现:先定类别,二分查找确定位置,移出空位
操作二实现:先定类别,再二分查找
这会带来两个问题:
问题一:空间如何分配?
每一类书的数目肯定不同,所以每类书的书架统一分多少吗?分少不够,多了又会浪费.
问题二:类别应该分多细?
类分的粗,同一类的书还是有很多;类分的细,类的规模又会很大.
结论:解决问题方法的效率,与数据的组织方式有关
关于空间使用
写程序实现一个函数PrintN,使得传入一个正整数N,顺序输出1-N所有正整数
程序法一:
#include<stdio.h>
#include<time.h>
clock_t start,stop;
double duration;
void PrintN(int N)
{
for(int i=1;i<=N;i++)
{
printf("%d\n",i);
}
}
int main()
{
start=clock();
PrintN(100000);
stop=clock();
duration=((double)(stop-start))/CLK_TCK;
printf("时间=%f\n",duration);
return 0;
}
运行结果:
程序法二:
#include<stdio.h>
#include<time.h>
clock_t start,stop;
double duration;
void PrintN(int N)
{
if(N)
{
PrintN(N-1);
printf("%d\n",N);
}
}
//递归,他把能用的空间全部吃掉还不够吃,就爆了 ,非正常终止
int main()
{
start=clock();
PrintN(100000);
stop=clock();
duration=((double)(stop-start))/CLK_TCK;
printf("时间=%f\n",duration);
return 0;
}
运行结果:非正常终止
结论:解决问题方法的效率与空间的利用效率有关
关于算法效率
计算多项式值-写程序计算给定多项式在给定点x处的值f(x)=a0+a1x+......+an
函数1:
double f(int n,double a[],double x)
{
double p=a[0];
for(int i=1;i<=n;i++)
{
p+=(a[i]*pow(x,i));
}
return p;
}
函数2:将x提出来,f(x)=a0+x(a1+x(a2...x(an-1+x(an))...))//秦九韶shao二声
double f(int n,double a[],double x)
{
double p=a[n];
for(int i=n;i>0;i--)
{
p=a[i-1]+p*x;
}
return p;
}
分别测试两个程序的运行时间,比较快慢
程序(对应函数1,2)
#include<stdio.h>
#include<math.h>
#include<time.h>
#define MAXN 10
#define MAXC 1e7//被测函数最大重复调用次数
clock_t start,stop;
double duration;
//f(x)=a0+a1x+......+anx^n
double f1(int n,double a[],double x)
{
double p=a[0];
for(int i=1;i<=n;i++)
{
p+=(a[i]*pow(x,i));
}
return p;
}
double f2(int n,double a[],double x)
{
double p=a[n];
for(int i=n;i>0;i--)
{
p=a[i-1]+p*x;
}
return p;
}
int main()
{
int i;
double a[MAXN];
for(i=0;i<MAXN;i++)
{
a[i]=(double)i;
}
//clock();捕捉从程序开始运行到clock()被调用时所耗费的时间.这个时间单位是clock tick,即"时钟打点"
start=clock();
for(i=0;i<MAXC;i++)
f1(MAXN-1,a,2.5);
stop=clock();
duration=((double)(stop-start))/CLK_TCK;//常数 CLK_TCK:机器时钟每秒所走的时钟打点数,在在VC++6.0,Dev中其值为1000。
printf("时间=%f\n",duration);
//---------------------------------------
start=clock();
for(i=0;i<MAXC;i++)
f2(MAXN-1,a,2.5);
stop=clock();
duration=((double)(stop-start))/CLK_TCK;
printf("时间=%f\n",duration);
return 0;
}
运行结果:
将MAXC换为1e8后运行结果:
可见秦九韶的第二种比第一种要快的多.
结论:解决问题方法的效率,与算法的巧妙程度有关
抽象数据类型(Abstract DateType)
到底什么是数据结构呢?
数据结构是关于数据对象在计算机中间的组织方式,也就是说书店里怎么存放图书的问题.
数据对象在计算机中间的组织方式:一个是关于数据对象的逻辑结构,另一个是数据对象在计算机里面的物理存储结构
逻辑结构:
比如说,按照如何摆放图书的法二:我们如果一开始把这个书架想象成简单的一个长条,这么一层架子,所有的书是一个接着一个放的,除了一头一尾的书,每本书他前面只有一本书,后面只有一本书.如果每一本书有一个编号的话,那么这种结构叫做一对一的结构,我们管它叫做"线性结构".
另外一种组织方式,就是我们的法三:先把图书分类,那如果我给每一类一个编号的话,那么这一个编号里面,对应着很多书,这是一个一对多的结构,我们管它叫做"树型结构".
还有图,一本书对应很多买家,一个买家又对应很多书,这是一个多对多的,很复杂的关系网,他就是对于的是图的结构
物理存储结构:也就是逻辑结构在机器的内存里到底要怎么一个放法,是连续放还是随便隔着放.也就是说是用数组存放呢,还是用一个链表呢?
数据对象必定与一系列加在其上的操作相关联,而实现这些操作所用的方法就是算法
描述数据结构的方法叫做抽象数据类型
抽象:描述数据类型的方法不依赖于具体实现
与存放数据的机器无关;与数据存储的物理结构无关;与实现操作的算法和编程语言均无关.
只描述数据对象集和相关操作集"是什么",并不涉及"如何做到"的问题
概括事务,抽取数据的共性,提高复用性,符合计算机的工作机制.
数据类型(java,c++就为这个数据类型专门设计了机制--类)
1.数据对象集
2.数据集合相关联的操作集
举几个例子(抽象数据类型):
类型名称:矩阵(Matrix)
Matrix Create(int M,int N):返回一个MxN的空矩阵
ElementType GetEntry(Matrix A,int i,int j):返回矩阵A的第i行,第j列的元素
Matrix Add(Matrix A,Matrix B):如果A和B行列一致,返回C=A+B,否则返回错误标志
未完持续......