概念和定义
什么是数据结构
数据结构就是数据对象在计算机中的组织方式,然后数据结构一定和加在他上面的操作相关联,而完成这些操作的的方法就是我们所说的算法,所以数据结构和算法这两个词往往是一起出现的。
就比如视频的例子图书馆,数据元素就是我们想要摆放进去的书,我们要怎么摆按什么方式摆就是我们的算法。
组织方式其实就是逻辑结构和物理结构。逻辑结构包含树,图等,物理结构包含顺序结构和链接结构。
算法的定义
算法的指令必须是一个有限集,可能有输入,必须要有输出,一定要有有限的步骤,且每一条指令必须没有奇异,在计算机能够处理的能力范围内。
在算法里,时间复杂度是十分重要的,所以我们还要学习一些计算时间复杂度的方法和技巧:
1 我们知道常数项对函数的增长速度影响不大,所以我们在计算时间复杂度的时候可以直接忽略常数项
比如一个程序的时间复杂度T(n)=4,那么我们可以说这个程序的时间复杂度为O(1),再比如一个程序的时间复杂度是T(n)=n+15,那么我们可以说这个程序的时间复杂度是O(n).
2 我们知道高次项对整个函数的增长速度影响最大,比如n的三次方比n的二次方速度大,同时因为要求的精度不高,所以我们在碰见有多个次项时可以忽略低次项,比如一个程序T(n)=n ^ 3+n ^ 2+15;那么我们可以直接计算为O(n)=n^3.
3 一个阶乘对函数的增长速度影响大,所以我们碰见高次项有常数时可以直接忽略常数,比如一个程序T(n)=3n^3,那么它的时间复杂度可以计算为O(n)=n ^3;
4 碰到一个循环的时候,先算出循环体的时间为多少记为n,再计算循环了多少次,记为m,总的时间复杂度就是O(mn)。如果是多个循环那么我们就要由里向外分析。
5对于顺序执行的,总的时间复杂度为其中最长的一个,比如一个顺序结构里有两次循环,第一个循环的时间复杂度为n ^ 2,第二个为n,那么总的时间复杂度就为O(n)=n ^ 2。
6对于判断语句,也是找其中时间复杂度最大的作为总时间复杂度
有了以上几种的方法和技巧,我们只要从内向外的分析,就可以计算出大概的时间复杂度。
题解
1
习题1.8 二分查找 (20分)
这道题是让我们写一个二分的函数,很简单,只要掌握二分的思想,每次都取中间看看比x大还是小,如果小了,那么就往右边找,大了就往左边找,题目的代码在下面。
Position BinarySearch( List L, ElementType X )
{
int left=1,right=L->Last;
while(left<=right)
{
int mid=(right+left)/2;
if(L->Data[mid]==X)
{
return mid;
}
else if(L->Data[mid]>X)
{
right=mid-1;
}
else if(L->Data[mid]<X)
{
left=mid+1;
}
}
return NotFound;
}
2
习题1.9 有序数组的插入 (20分)
先判断数组是否满了,然后一直与数组中的数比较分两种情况,一种是在数组的中间找到了可插入的位置,另一种是一直没找到,一直到末尾才符合条件
bool Insert( List L, ElementType X )
{
int i,j;
if(L->Last==MAXSIZE-1)
{
return false;
}
for(i=0;i<=L->Last;i++)
{
if(L->Data[i]==X)
return false;
else if(L->Data[i]<X)
{
for(j=L->Last;j>=i;j--)
{
L->Data[j+1]=L->Data[j];
}
L->Data[i]=X;
L->Last=L->Last+1;//一定要注意要加一个
break;
}
else if(L->Last==i&&L->Data[i]>X)
{
L->Data[i+1]=X;
L->Last=L->Last+1;
break;
}
}
return true;
}
3
实例1.1 最大子列和问题 (20分)
这个是ppt中的一道题,最开始考虑的尺取但是感觉好像实现起来很复杂,最后看了视频的讲解懂了,用的是一种在线处理的方法,就是定义一个thissum先存放当前连续序列加起来的值,如果是负的就直接舍弃,因为,负数不会对后面的序列相加有帮助,不会使后面越来越大,所以一旦是负数就直接舍弃。如果当前的总和比之前的大就更新
#include<stdio.h>
int zilie(int a[],int n)
{
int thissum,maxsum;
int i;
thissum=maxsum=0;
for(i=0;i<n;i++)
{
thissum=thissum+a[i];
if(thissum>maxsum)
maxsum=thissum;//更新maxsum
else if(thissum<0)//如果小于零就直接舍弃,重新计算
thissum=0;
}
return maxsum;
}
int main()
{
int n;
int i;
int a[100010];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("%d\n",zilie(a,n));
}