第一讲基本概念——数据结构慕课笔记

数据结构基本概念——慕课笔记


代码来源:https://www.icourse163.org/course/ZJU-93001#/info

1.1什么是数据结构

1.1.1时钟打点的概念
  • 常数CLK_TCK(或CLOCKS_PER_SEC):机器时钟每秒所走的时钟打点数
  • clock():捕捉从程序开始运行clock()被调用时所耗费的时间。这个时间单位是clock tick,即“时钟打点”。
#include <stdio.h>
#include <time.h>//使用clock相关函数需包含的头文件

clock_t start, stop;
//clock_t是clock()函数返回的变量类型
double duration;
//记录被测函数运行时间,以秒为单位
int main ()
{
    
    
	start = clock();//开始计时
	MyFunction();//被测函数
	stop = clock();//停止计时
	duration = ((double)(stop - start))/CLK_TCK;//计算运行时间(开始与结束的时钟打点之差除时钟每秒所走的时钟打点数)
	return 0;
}

1.3应用实例:最大子列和问题

1.3.1最大子列和问题
  • 问题

在这里插入图片描述

  • 算法1(T(N)=O(N^3))
int MaxSubseqSum1(int A[] , int N){
    
    
    int ThisSum,MaxSum = 0;
    int i ,j ,k;
    for ( i = 0 ; i < N ; ++i){
    
    //i是子列最左端的位置
        for ( j = 0 ; 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;
}
  • 算法2(T(N)=O(N^2))
int MaxSubseqSum1(int A[] , int N){
    
    
    int ThisSum,MaxSum = 0;
    int i ,j ,k;
    for ( i = 0 ; i < N ; ++i){
    
    //i是子列最左端的位置
        ThisSum = 0//每轮循环(即每次移动左端点)ThisSum均需归零
        for ( j = i ; j < N ; ++j){
    
     //j是子列最右端的位置
            ThisSum += A[j]//递推公式 f(i,j) =f(i,j-1)+A[j]
          	if (ThisSum > MaxSum) //新得到的子列和更大
                MaxSum = ThisSum;//更新结果
        }//循环j结束
    }//循环i结束
    return Maxsum;
}
  • 算法三 分治T(N)=O(NlogN)

    • 思想:先分后治,先将大问题拆分成小的子问题,递归解决子问题的子问题从而合并几个子问题的结果解决整个问题(例如序列有八个元素a[0]-a[7]

      • 先分:不断地将数列二分又二分(递归的过程)直至数列只有一个元素停止递归,求出该子问题的结果,接着以该结果返回上一步的递归求出上一步的结果,最后求解整个问题的结果
      • 后治:对于每个拆分的子列,先求中线两边的子列的最大和,再求跨越中线的子列的最大和
      • 流程图

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ae1qS4IS-1586352804779)(C:\Users\YZN\AppData\Roaming\Typora\typora-user-images\image-20200404145632320.png)]
      在这里插入图片描述

int Max3( int A, int B, int C )
{
    
     /* 返回3个整数中的最大值 */
    return A > B ? A > C ? A : C : B > C ? B : C;//条件表达式结合顺序为自右向左
    //等价于 A > B ? (A > C ? A : C ) : (B > C ? B : C)
}
 
int DivideAndConquer( int List[], int left, int right )
{
    
     /* 分治法求List[left]到List[right]的最大子列和 */
    int MaxLeftSum, MaxRightSum; /* 存放左右子问题的解 */
    int MaxLeftBorderSum, MaxRightBorderSum; /*存放跨分界线的结果*/
 
    int LeftBorderSum, RightBorderSum;
    int center, i;
 
    if( left == right )  {
    
     /* 递归的终止条件,子列只有1个数字 */
        if( List[left] > 0 )  return List[left];//正数返回该子列数值,负数则为0
        else return 0;
    }
 
    /* 下面是"分"的过程 */
    center = ( left + right ) / 2; /* 找到中分点 */
    /* 递归求得两边子列的最大和 */
    MaxLeftSum = DivideAndConquer( List, left, center );
    MaxRightSum = DivideAndConquer( List, center+1, right );
 
    /* 下面求跨分界线的最大子列和 */
    MaxLeftBorderSum = 0; LeftBorderSum = 0;
    for( i=center; i>=left; i-- ) {
    
     /* 从中线向左扫描 */
        LeftBorderSum += List[i];
        if( LeftBorderSum > MaxLeftBorderSum )
            MaxLeftBorderSum = LeftBorderSum;
    } /* 左边扫描结束 */
 
    MaxRightBorderSum = 0; RightBorderSum = 0;
    for( i=center+1; i<=right; i++ ) {
    
     /* 从中线向右扫描 */
        RightBorderSum += List[i];
        if( RightBorderSum > MaxRightBorderSum )
            MaxRightBorderSum = RightBorderSum;
    } /* 右边扫描结束 */
 
    /* 下面返回"治"的结果 */
    return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
}
 
int MaxSubseqSum3( int List[], int N )
{
    
     /* 保持与前2种算法相同的函数接口 */
    return DivideAndConquer( List, 0, N-1 );
}
  • 算法4 在线处理(T(N)=O(N))
    • 每输入一个数据就进行即时处理,在任何一个地方中止输入,算法都能正确给出当前的解
    • 核心思路:由于要求解的问题是连续子列的最大和,所以当某一连续子列和为负数时,整个子列都可以舍弃(因为负数必然使后续子列和减小)
int MaxSubseqSum4( int A[], int N )
{
    
     	int ThisSum, MaxSum;
	int i;
	ThisSum = MaxSum = 0;
	for( i = 0; i < N; i++ ) {
    
    
		ThisSum += A[i]; /* 向右累加*/
	if( ThisSum > MaxSum )
		MaxSum = ThisSum; /* 发现更大和则更新当前结果*/
	else if( ThisSum < 0 ) /* 如果当前子列和为负*/
		ThisSum = 0; /* 则不可能使后面的部分和增大,抛弃之*/
	}
	return MaxSum;
}

猜你喜欢

转载自blog.csdn.net/jimmy33777/article/details/105397669
今日推荐