开始学数据结构——(四):归并排序

/*
归并排序。 思路很简单,就是不断的将要排序的数组进行分割,然后直到只有一个数的时候,那么这个时候就是已经排好序的了。 然后将这两部分数存放在不同的两个数组中,两边都从最小的部分开始往外读,回归到排序数组中即可。    
SQ 2014.4.14
*/

#include<stdio.h>

int aa[10]={10,8,9,7,6,4,5,3,1,2};
void merge(int start , int mid , int end){
    
    int left[10];
    int right[10];
    int i , j , k;
    int n1 ,n2;   //用于存放左右两部分的长度
    n1 = mid -start +1;// 比如 0-5 吧,其实这里的数据是6个 然后就是 <5-0 +1>;
    
    n2= end -mid;
    
     for(i =0 ; i < n1 ;i++)  //将待排序的左半部分存放在数组中
        left[i] = aa[start +i];

     for(j=0 ; j < n2 ; j++)  
        right[j] = aa[j + mid +1];
    
    i=j=0;    
    for ( k= start; i < n1 && j <n2 ;k++ ) {  // 从两个数组中按大小取出数列
        if (left[i] <= right[j]){  //如果左边的小于右边的,则取左边的 然后左边的+1;
            aa[k] = left[i];
            i++;
            
        }
        
        else if(left[i] > right[j]) {
            aa[k] = right[j];
            j++;
        }    
    }

    for (; i < n1; i ++) {
        aa[k] = left[i];
            k++;
            }

    for(; j < n2 ; j++){
        aa[i+j] = right[j];
            k++;        
    }        
    }
//开始写分割函数
void sort(int start ,int end ){

    int mid ;
    
    if (start < end)  {
        mid = (start + end )/2 ;

        sort (start ,mid );  //这里是偶数的话倒没有问题,奇数的话左半部分的比右半部分的多一;
            
        sort (mid +1 ,end);
        merge( start ,mid ,end);    
    }
}


int main(){
    int i;
    for(i=0 ; i < 10 ;i++)
        printf("%d \n" ,aa[i]);
    sort(0 , 9);    
    printf("after sort()\n");
    for(i=0 ; i < 10 ;i++)
        printf( "%d \n " ,aa[i]);


return 0;
}


分析时间复杂度:

归并排序及其时间复杂度分析 - 珑儿 - 顾影自怜

       这是一个递推公式(Recurrence),我们需要消去等号右侧的T(n),把T(n)写成n的函数。其实符合一定条件的Recurrence的展开有数学公式可以套,这里我们略去严格的数学证明,只是从直观上看一下这个递推公式的结果。当n=1时可以设T(1)=c1,当n>1时可以设T(n)=2T(n/2)+c2n,我们取c1和c2中较大的一个设为c,把原来的公式改为:

归并排序及其时间复杂度分析 - 珑儿 - 顾影自怜

       这样计算出的结果应该是T(n)的上界。下面我们把T(n/2)展开成2T(n/4)+cn/2(下图中的(c)),然后再把T(n/4)进一步展开,直到最后全部变成T(1)=c(下图中的(d)):

归并排序及其时间复杂度分析 - 珑儿 - 顾影自怜

       把图(d)中所有的项加起来就是总的执行时间。这是一个树状结构,每一层的和都是cn,共有lgn+1层,因此总的执行时间是cnlgn+cn,相比nlgn来说,cn项可以忽略,因此T(n)的上界是Θ(nlgn)。

       如果先前取c1和c2中较小的一个设为c,计算出的结果应该是T(n)的下界,然而推导过程一样,结果也是Θ(nlgn)。既然T(n)的上下界都是Θ(nlgn),显然T(n)就是Θ(nlgn)。

空间复杂度的话显然是O(n).因为这里只需要一个数组来存放左右两部分数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值