前言:本文为数据结构之基本概念,根据陈越姥姥的网课而整合的笔记。
我们以几个栗子展开解释:
栗子1:如何在书架上摆放图书?——如何在空间中储存数据?
图书的摆放需要有2个相关操作来实现
操作1:新书怎么插入? 操作2:怎么找到指定的某本书?
方法1:随便放(操作1实现简易,操作2实现困难)
方法2:按照书名的拼音字母顺序排放,二分法查找书(操作1实现困难,操作2 实现简易)
方法3:把书分成类别划分书架区域,按照书名的拼音字母顺序排放(操作1,操作2 均实现容易)
总结:解决问题方法的效率跟数据的组织方式有关。
栗子2:写程序实现一个函数PrintN,使得传入一个正整数为N的参数后,能顺序打印从1到N的全部正整数
方法一:循环实现
void PrintN(int N)
{
int i;
for(i=1;i<=N'i++){
printf("%d\n",i);
}
return;
}
方法二:递归实现
void PrintN(int N)
{
if(N){
PrintN(N-1);
printf("%d\n",N);
}
return;
}
当代入N为100,1000,10000,10000…时,会发现N过于大时,方法二因内存过大不执行。
总结:解决问题方法的效率,跟空间的利用效率有关。
栗子3:写程序计算给定多项式在给定点x处的值
方法一:f(x)=a(0)+a(1)x+…+a(n)x**(n)
double f(int n,double a[],double x)
{
int i;
double p=a[0];
for(i=1;i<=n;i++)
p+=(a[i]*pow(x,i));
return p;
}
方法二:f(x)=a(0)+x(a(1)+x(…(a(n-1)+x(a(n)))…))
double f(int n,double a[],double x)
{
int i;
double p=a[n];
for(i=n;i>0;i--)
p=a[i-1]+x*p;
return p;
}
调用clock()计算程序运行时间,发现方法二单次运行的时间较长。
总结:解决问题方法的效率,跟算法的巧妙程度有关。
1.数据对象在计算机中的组织方式
(1)逻辑结构
(2)物理存储结构
以数组储存还是以链表储存
2.数据对象必定与一系列加在其上的操作相关联
3.完成这些操作所用的方法就是算法
抽象数据类型
数据类型
抽象:描述数据类型的方法不依赖于具体实现
只描述数据对象集合相关操作机”是什么“,并不涉及“如何做到”的问题
总结:没有完美的数据结构,只有最合适的数据结构。应该因地制宜,不同的用途(查找、插入…)采用不同的数据结构来提高效率
1.一个有限指令集
2.接受一些输入(有些情况下不需要输入)
3.产生输出
4.一定在有限步骤之后终止
5.每一条指令必须
题目:给定N个整数的序列{A1,A2,…,AN},求函数f(i,j)=max{0,{Ai+A(i+1)+…+Aj}}的最大值。
算法1:
int MaxSubseqSum1(int A[],int N)
{
int ThisSum, MaxSum = 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 MaxSubseqSum2(int A[],int N)
{
int ThisSum, MaxSum = 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次循环的基础上累加1项即可*/
if(ThisSum>MaxSum) /*如果刚得到的这个子列和更大*/
MaxSum=ThisSum; /*则更新结果*/
}/*j循环结束*/
}/*i循环结束*/
return MaxSum;
T(N)=O(N**2)
算法3:分而治之
把一个比较大的复杂的问题切分成小的块,然后分头去解决它们,最后再把结果合并起来,这就是“分而治之”
对于此问题,假设该问题是放在一个数组里面,首先第一步是”分“,也就是把这个数组从中间一分为二,然后递归地去解决左右两边的问题。递归地去解决左边的问题,我们会得到左边的一个最大子列和;递归地去解决右边的问题,我们会得到右边的一个最大子列和。还有一种情况时跨越边界的最大子列和。把这三个结果合成起来就叫做“治”。
算法4:在线处理
int MaxSubseqSum4(int A[],int N)
{
int ThisSum, MaxSum;
int i;
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)
"在线"的意思是指每输入一个数据就进行即时处理,在任何一个地方中止输入,算法都能正确给出当前的解。
可知第四种算法更为优解。
声明:部分资料源自网络,如有侵权,请联系我删除!
文中如存在谬误、混淆等不足,欢迎批评指正!