zoukankan      html  css  js  c++  java
  • 归并排序

    归并排序

    归并排序是将两个有序的数组归并成一个更大的有序数组,要对一个数组排序,可以先不断递归地将数组分为两半进行排序,最后再将结果归并起来。归并排序最吸引人的性质是它能保证任意长度为N的数组所需时间和NlogN成正比,它的主要缺点是它所需的额外空间和N成正比。

    图1-1的树状图显示了要将arr[0]到arr[6],7个元素的数组排序,归并排序的分治思想会先将整个数组通过递归不断拆解成一个个小数组进行归并,再将两两已经排序好的小数组再进行归并排序,一直到整个数组排序完毕。

                     图1-1

     从图1-1可以看出,如果一棵树正好有n层,对于0到n-1之间的任意k,自顶向下的第k层有2k个子数组,每个数组长度为2n-k,归并最多需要2n-k次比较,因此每层的比较次数为2k*2n-k=2n,n层总共为n2n=Nlog(N),因此,归并排序的时间复杂度为O(nlogn)

    代码1-2为归并排序的C语言实现

    #include <stdio.h>
    
    void sort( int arr[], int tmp_arr[], int left, int right );
    
    
    void merge( int arr[], int tmp_arr[], int left, int mid, int right );
    
    
    void sort( int arr[], int tmp_arr[], int left, int right )
    {
    	int mid = (left + right) / 2;
    	if ( left >= right )
    	{
    		return;
    	}
    	sort( arr, tmp_arr, left, mid );
    	sort( arr, tmp_arr, mid + 1, right );
    	merge( arr, tmp_arr, left, mid, right );
    }
    
    
    void merge( int arr[], int tmp_arr[], int left, int mid, int right )
    {
    	int i = left, j = mid + 1, k = 0, len = right - left + 1;
    	for ( k = left; k <= right; k++ )
    	{
    		tmp_arr[k] = arr[k];
    	}
    	k = left;
    	while ( i <= mid && j <= right )
    	{
    		if ( tmp_arr[i] > tmp_arr[j] )
    		{
    			arr[k] = tmp_arr[j++];
    		}else{
    			arr[k] = tmp_arr[i++];
    		}
    		k++;
    	}
    	while ( i <= mid )
    	{
    		arr[k++] = tmp_arr[i++];
    	}
    	while ( j <= right )
    	{
    		arr[k++] = tmp_arr[j++];
    	}
    }
    
    
    void main()
    {
    	int	i	= 0;
    	int	arr[]	= { 1, 10, -5, 9, 8, 7, 3 };
    	int	len	= sizeof(arr) / sizeof(arr[0]);
    	int	tmp_arr[len];
    	printf( "待排序数组:" );
    	for ( i = 0; i < len; i++ )
    	{
    		printf( "%d ", arr[i] );
    	}
    	printf( "
    " );
    	sort( arr, tmp_arr, 0, len - 1 );
    	printf( "排序后数组:" );
    	for ( i = 0; i < len; i++ )
    	{
    		printf( "%d ", arr[i] );
    	}
    }
    

     

    代码1-3位归并排序的Java实现

    import java.util.Arrays;
    
    public class Merge {
    
    	public static void merge(int[] arr, int[] tmpArr, int left, int mid, int right) {
    		int i = left, j = mid + 1, k = 0;
    		for (k = left; k <= right; k++) {
    			tmpArr[k] = arr[k];
    		}
    		k = left;
    		while (i <= mid && j <= right) {
    			if (tmpArr[i] > tmpArr[j]) {
    				arr[k] = tmpArr[j++];
    			} else {
    				arr[k] = tmpArr[i++];
    			}
    			k++;
    		}
    		while (i <= mid) {
    			arr[k++] = tmpArr[i++];
    		}
    		while (j <= right) {
    			arr[k++] = tmpArr[j++];
    		}
    	}
    
    	public static void sort(int[] arr, int[] tmpArr, int left, int right) {
    		if (left >= right) {
    			return;
    		}
    		int mid = (left + right) / 2;
    		sort(arr, tmpArr, left, mid);
    		sort(arr, tmpArr, mid + 1, right);
    		merge(arr, tmpArr, left, mid, right);
    	}
    
    	public static void main(String[] args) {
    		int[] arr = { 1, 10, -5, 9, 8, 7, 3 };
    		int[] tmpArr = new int[arr.length];
    		System.out.print("待排序数组:" + Arrays.toString(arr));
    		System.out.println();
    		sort(arr, tmpArr, 0, arr.length - 1);
    		System.out.println("排序后数组:" + Arrays.toString(arr));
    	}
    
    }
    

      

    代码1-4为归并排下序的Python实现

    # coding:utf-8
    def merge(left, right):
        i, j = 0, 0
        result = []
        while i < len(left) and j < len(right):
            if left[i] > right[j]:
                result.append(right[j])
                j += 1
            else:
                result.append(left[i])
                i += 1
        result += left[i:]
        result += right[j:]
        return result
    
    
    def sort(arr):
        if len(arr) <= 1: return arr
        mid = int(len(arr) / 2)
        left = sort(arr[:mid])
        right = sort(arr[mid:])
        return merge(left, right)
    
    
    arr = [1, 10, -5, 9, 8, 7, 3]
    print "待排序数组:", arr
    print "排序后数组", sort(arr)
    

      

    代码1-5为归并排序的Scala实现

    import java.util.Arrays
    
    object Merge {
    
      def sort(comparator: (Int, Int) => Boolean)(list: List[Int]): List[Int] = {
        val mid = list.size / 2
        if (mid == 0) list
        else {
          def merge(xs: List[Int], ys: List[Int]): List[Int] = (xs, ys) match {
            case (Nil, ys) => ys
            case (xs, Nil) => xs
            case (x :: nxs, y :: nys) =>
              if (comparator(x, y)) y :: merge(xs, nys)
              else x :: merge(nxs, ys)
          }
          val (left, right) = list splitAt mid
          merge(sort(comparator)(left), sort(comparator)(right))
        }
      }
    
      def main(args: Array[String]): Unit = {
        val list = List(1, 10, -5, 9, 8, 7, 3)
        println("待排序数组:" + Arrays.toString(list.toArray))
        println("排序后数组:" + Arrays.toString(sort(_ > _)(list).toArray))
      }
    }
    

      

  • 相关阅读:
    根据表生成接收(zml)
    删除指定日期,指定设备的排产记录(zml)
    1029 Median
    1027 Colors in Mars (20 分)进制转换
    1028 List Sorting 排序
    1025 PAT Ranking
    1024 Palindromic Number(大数加法)
    1023 Have Fun with Numbers
    1022 Digital Library
    逆序打印乘法表
  • 原文地址:https://www.cnblogs.com/fuxinyue/p/6925885.html
Copyright © 2011-2022 走看看