基本概率啥的就不搬书上的了,主要写写我自己的体会。
数据结构与算法
数据结构:我觉得数据结构是一种人为精心选择的存储数据的方式,用以解决现实生活中数据间的复杂关系,我们学习的栈,队列等只是数据结构的基础,根据实际题目等可以选取便利的数据结构,甚至自己拼凑、修改出一个最适合的数据结构。总而言之,我认为数据结构是存储数据的一种模板。
算法:算法与数据结构经常放在一起讲,起初我一直不大明白是为什么,而现在我认为在我们选取了合适的数据结构之后,我们需要解决实际的问题,而解决实际的问题的方法便是算法。
程序=数据结构+算法
时间复杂度
解决实际问题的方法有很多种,而衡量一个算法是否优秀的依据便是时间复杂度与空间复杂度。
时间复杂度的理解:一般来说,数据越大越多的话,运行时间越久。我们不可能每次都去测试一下程序运行的时间,那样很蠢。所以时间复杂度是一种不运行程序的粗略的估计程序时间的方法。
而我们学过数学也知道,一般而言,但数据较大的时候,最高次项对结果的影响最大,所以我们为了方便,便只保留最高次项,并且因为计算器很多时候数据过于巨大,我们也可以忽略掉最高次项前的系数。
时间复杂度的计算其实很简单,看程序中有多少个循环,如果有2个从0到n的循环时间复杂度便是n。而一个嵌套相当于一个n2,两个嵌套相当于n3。
较为常见的算法时间复杂度有n3,n2,n,n logn , log n,1,其中最优秀的肯定是1,不过较为少见,正常一个较好的算法他的时间复杂度为nlogn,我们在写出n2的算法时,应该考虑是否可以优化到nlogn。
题目
实例1.1 最大子列和问题
这个题我的第一想法就是用尺取去求。
在线算法,刚刚开始并没有看懂是啥意思。他其实就是一个聪明的尺取,他先从第一个开始加,输入一个就加一个,与之前的最大值比较更换最大值。直到和小于0了,重新开始计数,最后求出最大子序列。这种算法叫做“在线”算法,我认为内涵其实应该是尺取。
#include <stdio.h>
int maxnum(int a[ ], int N );
int main()
{
int K;
while(~scanf("%d",&K))
{
int a[100010];
for(int i=0;i<K;i++)
{
scanf("%d",&a[i]);
}
printf("%d\n",maxnum(a,K));
}
}
int maxnum(int a[ ], int N )
{
int ThisSum, MaxSum, j;
ThisSum = MaxSum = 0;
for ( int i = 0; i < N; i++ )
{
ThisSum += a[ i ];
if ( ThisSum > MaxSum )
MaxSum = ThisSum;
else if ( ThisSum < 0 )
ThisSum = 0;
}
return MaxSum;
}
习题1.8 二分查找
二分其实就是一个数学思想,查找一个东西,不断二分查找是最快的方法。
习题1.8 二分查找
Position BinarySearch( List L, ElementType X )
{
int left=1,right=L->Last;
int ans;
while(left<=right)
{
int mid=(left+right)/2;
if(L->Data[mid]==X)
{
ans=mid;
return ans;
}
else if(L->Data[mid]<X)
{
left=mid+1;
}
else if(L->Data[mid]>X)
{
right=mid-1;
}
}
return NotFound;
}
习题1.9 有序数组的插入
这个很简单,插入就完事了。
习题1.9 有序数组的插入
bool Insert( List L, ElementType X )
{
if(L->Last==MAXSIZE-1)
{
return false;
}
for(int i=0;i<=L->Last;i++)
{
if(L->Data[i]==X)
{
return false;
}
else if(L->Data[i]<X)
{
for(int j=L->Last;j>=i;j--)
{
L->Data[j+1]=L->Data[j];
}
L->Data[i]=X;
L->Last++;
return true;
}
}
L->Data[L->Last+1]=X;
L->Last++;
return true;
}
理解了数据结构与算法基本概率之后,我们就开始正式学习数据结构了。