• 归并排序算法学习笔记


    归并排序也是一种分治思想的典型应用,把两个或两个以上的有序表合并成一个有序表,即把待排序序列分成若干子序列,每个子序列是有序的,之后再把有序子序列合并成整体有序序列。

    归并排序的平均时间复杂度为O(nlogn),最坏情况为O(nlogn),最优情况为O(n),空间复杂度为O(n),因为排序过程中要用到暂存区,所以该算法比较耗内存,但是效率比较高且是稳定排序。

    归并排序的递归版本如下:

    void Merge(int a[], int first, int mid, int last, int temp[]){
    	int i, j, k;
    	i = first;
    	j = mid + 1;
    	k = first;
    	while(i <= mid && j <= last){
    		if(a[i] < a[j])
    			temp[k++] = a[i++];
    		else
    			temp[k++] = a[j++];
    	}
    	while(i <= mid)
    		temp[k++] = a[i++];
    	while(j <= last)
    		temp[k++] = a[j++];
    
    	i = k = first;
    	while(i <= last && k <= last){  // 把排好序的暂存区回写到原序列中
    	    a[i++] = temp[k++];
    	  }
    }
    void mergesort(int a[], int first, int last, int temp[]){
    	if(first < last){
    		int mid = (first + last)/2;
    		mergesort(a, first, mid, temp);
    		mergesort(a, mid + 1, last, temp);
    		Merge(a,first, mid, last, temp);
    	}
    }
    归并排序非递归版本如下:

    void mergesortNonRecursion(int a[], int n, int temp[]){
         int size = 1, low, mid, high;
         while(size <= n-1){ // 递归版其实是把序列每次1/2的往下分解,非递归就是这个过程逆过来,用两个循环,外循环加倍步长size,内循环用size分割子序列,分段合并子序列
             low = 0;
             while(low + size <= n-1){
                 mid = low + size-1;
                 high = mid + size;
                 if(high > n - 1)
                   high = n - 1;
                 Merge(a, low, mid, high, temp);
                 printf("low:%d  mid:%d  high:%d  ", low, mid, high);
                 low = high + 1;
               }
             size *= 2;
           }
    }
    
    和快速排序算法一样,归并排序的非递归版本应该也能用栈来模拟实现,以后有时间再实现吧!



  • 相关阅读:
    Linux开机流程【原创】
    Linux下无需按下回车(无阻塞)读取输入键值
    Sql Server 列转行 Pivot使用
    mysql
    mysql
    mysql
    CI
    mysql
    Snagit: Scrolling is not working
    Something about SnagIt
  • 原文地址:https://www.cnblogs.com/Harry-Lord/p/4002847.html
Copyright © 2020-2023  润新知