zoukankan      html  css  js  c++  java
  • 分治法之归并排序

    上一篇博文介绍了分治法的思想,这一篇我们来了解一下分治法在排序问题中的应用--二路归并排序MergeSort

    所谓归并排序是指将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(或有序表)

    算法设计思路:

    输入:待排序数组a[n],待排序区间[s,t];
    输出:升序序列a[s]~a[t]
    1 如果s==t,则待排区间只有一个元素,算法结束
    2 计算划分中点 m=(s+t)>>1;
    3 对前半个子序列a[s]~a[m]进行升序排列
    4 对后半个子序列a[m+1]~a[t]进行升序排列
    5 合并两个升序序列a[s]~a[m]和a[m+1]~a[t]

    算法实现代码(C++)

    #include <stdio.h>
    const int MAX=20;
    //合并两个有序数组中的元素到数组b
    void Merge(int a[],int b[],int s,int m,int t)//算法时间复杂度O(n)
    {
    	int i=s,j=m+1,k=s;
    	while(i<=m && j<=t)//取较小者放入b[k]
    	{
    		if(a[i]<=a[j])
    			b[k++]=a[i++];
    		else
    			b[k++]=a[j++];
    	}
    	while(i<=m)
    		b[k++]=a[i++];
    	while(j<=t)
    		b[k++]=a[j++];
    }
    void MergeSort(int a[],int s,int t)
    {
    	int m,b[MAX];
    	if(s==t)
    		return ;//平凡问题,递归边界条件,只有一个记录,已经有序
    	else
    	{
    		m=(s+t)>>1;
    		MergeSort(a,s,m);
    		MergeSort(a,m+1,t);
    		Merge(a,b,s,m,t);
    		for(int i=s;i<=t;i++)
    			a[i]=b[i];
    	}
    }
    extern void test1()
    {
    		 int length,i;
    		 int num[MAX];
    		 printf("请输入待排序的数组长度(按ctrl+z结束)
    ");
    		 while(scanf("%d",&length)!=EOF)
    		 {
    			 printf("请依次输入数组元素
    ");
    			 for(i=0;i<length;i++)
    				 scanf("%d",num+i);
    
    			 MergeSort(num,0,length-1);
    			 printf("
    -------------------------------------------
    ");
    			 printf("归并排序后输出元素序列
    ");
    			 for(int i=0;i<length;i++)
    				 printf("%d	",num[i]);
    			 printf("
    ");
    			 for(i=0;i<length;i++)//清零
    				 num[i]=0;
    			 printf("请输入待排序的数组长度(按ctrl+z结束)
    ");
    		 }
    }
    

      算法实现分析:

    空间复杂度:归并排序需要多元序列上的两个子序列操作,因此不能直接在原序列上进行,需要一个与原序列相同的辅助空间,因此空间复杂度为O(n)

    时间复杂度:设待排序列个数为n,则执行一趟合并操作算法时间复杂度为o(n),当n=1时,直接返回,即不耗时间T(1)=0;

    总的时间复杂度为t(n)=O(nlogn) 

  • 相关阅读:
    Angular使用总结 --- 如何正确的操作DOM
    JavaScript 全屏展示
    JavaScript getter和setter
    Angular使用总结 --- 模型驱动表单
    JavaScript 那些不经意间发生的数据类型自动转换
    JavaScript 判断对象中是否有某属性
    Angular使用总结 --- 搜索场景中使用rxjs的操作符
    Angular使用总结 --- 以密码确认为例实现模版驱动表单的自定义校验
    js几种继承模式(传统,call/apply,共享原型,圣杯模式)
    call和apply的用法与区别
  • 原文地址:https://www.cnblogs.com/gaochaochao/p/8891756.html
Copyright © 2011-2022 走看看