(一)什么是数据结构?
“数据结构是数据对象,以及存在于该对象的实例和
组成实例的数据元素之间的各种联系。这些联系可以通过定义相关的函数来给出。”
Sartaj Sahni,《数据结构、算法与应用》
“数据结构是ADT(抽象数据类型Abstract DataType)的物理实现。”
Clifford A.Shaffer,《数据结构与算法分析》
“数据结构(data structure)是计算机中存储、组织
数据的方式。通常情况下,精心选择的数据结构可以带来最优效率的算法。”
思考:
1.如何在图书架上摆放图书?
(1)新书如何插入?
(2)如何找到特定的那本书?
说明:
解决问题方法的效率,
(二)什么是算法?
定义
算法(Algorithm)
-
一个有限指令集
-
接受一些输入(有些情况下不需要输入)
-
产生输出
-
一定在有限步骤之后终止
每一条指令必须
有充分明确的目标,不可以有歧义
计算机能处理的范围之内
描述应不依赖于任何一种计算机语言以及具体的实现手段
什么是好的算法?
空间复杂度S(n)—— 根据算法写成的程序在执行时占用存储单元的长度。这个长度往往与输入数据的规模有关。空间复杂度过高的算法可能导致使用的内存超限,造成程序非正常中断。
时间复杂度T(n)—— 根据算法写成的程序在执行时耗费时间的长度。这个长度往往也与输入数据的规模有关。时间复杂度过高的低效算法可能导致我们在有生之年都等不到运行结果。
在分析一般算法的效率时,我们经常关注下面两种复杂度
最坏情况复杂度 Tworst(n )
平均复杂度 Tavg(n )
Tavg(n) Tworst(n)
复杂度的渐进表示法
T(n) = O(f(n))表示存在常数C>0, n0>0使得当nn0时有T(n) C·f(n)
T(n) = Ω(g(n))表示存在常数C>0, n0>0使得当nn0时有T(n) C·g(n)
T(n) = Θ(h(n))表示同时有T(n) = O(h(n))和T(n) = Ω(h(n))
复杂度分析小窍门
若两段算法分别有复杂度T1(n) = O(f1(n))和T2(n) =O(f2(n)),则
T1(n) + T2(n) = max( O(f1(n)), O(f2(n)) )
T1(n) T2(n) = O( f1(n) f2(n) )
-
若T(n)是关于n的k阶多项式,那么T(n)=Θ(nk)
-
-
一个for循环的时间复杂度等于循环次数乘以循环体
代码的复杂度
if-else结构的复杂度取决于if的条件判断复杂度
和两个分枝部分的复杂度,总体复杂度取三者中最大
(三)应用实例:最大子列和问题
给定N个整数的序列{A1,A2, ...,AN},j 求函数f(i,j)max{0,A}的最大值。
算法1
int MaxSubseqSum1( int A[], int N )
{ int ThisSum, MaxSum = 0;
}
inti, 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++ )
kki
ThisSum += A[k];
if( ThisSum > MaxSum )/*如果刚得到的这个子列和更大 */
MaxSum = ThisSum;}/* j循环结束*/
/*则更新结果 */
}/* i循环结束*/returnMaxSum;
T(N ) = O(N3)
/*最大子列和问题-----算法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;
}
时间复杂度:O(N^2)
/*最大子列和问题-----算法3*/
int MaxSubseqSum3( int A[] , int N)
{
int ThisSum , MaxSum ;
int i ;
ThisSum = MaxSum = 0 ;
for( i = 0 ; i < N ; i++ ) /*i是子列左端位置 */
{
ThisSum += A[i]; /*向右累加*/
if( ThisSum > MaxSum )
MaxSum = ThisSum ; /*发现更大的则更新结果*/
else if( ThisSum < 0 ) /*如果当前子列为负*/
ThisSum = 0 ; /*则不可能使后面的部分和增大*/
}
return MaxSum;
}
时间复杂度:O(N)