合并排序算法-c++

来源:互联网 发布:淘宝发货快递公司填错 编辑:程序博客网 时间:2024/06/02 02:39

参考来源:http://www.cnblogs.com/yangecnu/p/Introduce-Merge-Sort.html
合并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序。合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行合并。
这里写图片描述
合并排序最大的优点是它的时间复杂度为O(nlgn),这个是我们之前的选择排序和插入排序所达不到的。他还是一种稳定性排序,也就是相等的元素在序列中的相对位置在排序前后不会发生变化。他的唯一缺点是,需要利用额外的N的空间来进行排序。

合并算法:
合并排序依赖于合并操作,即将两个已经排序的序列合并成一个序列,具体的过程如下:
1、申请空间,使其大小为两个已经排序序列之和,然后将待排序数组复制到该数组中。
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置
3、比较复制数组中两个指针所指向的元素,选择相对小的元素放入到原始待排序数组中,并移动指针到下一位置
4、重复步骤3直到某一指针达到序列尾
5、将另一序列剩下的所有元素直接复制到原始数组末尾
实现代码:

private static void Merge(T[] array, int lo, int mid, int hi){    int i = lo, j = mid + 1;    //把元素拷贝到辅助数组中    for (int k = lo; k <= hi; k++)    {        aux[k] = array[k];    }    //然后按照规则将数据从辅助数组中拷贝回原始的array中    for (int k = lo; k <= hi; k++)    {        //如果左边元素没了, 直接将右边的剩余元素都合并到到原数组中        if (i > mid)        {            array[k] = aux[j++];        }//如果右边元素没有了,直接将所有左边剩余元素都合并到原数组中        else if (j > hi)        {            array[k] = aux[i++];        }//如果左边右边小,则将左边的元素拷贝到原数组中        else if (aux[i].CompareTo(aux[j]) < 0)        {            array[k] = aux[i++];        }        else        {            array[k] = aux[j++];        }    }}
下图是使用以上方法将EEGMR和ACERT这两个有序序列合并为一个大的序列的过程演示:

这里写图片描述
合并排序算法:合并排序有两种实现,一种是至上而下(Top-Down)合并,一种是至下而上 (Bottom-Up)合并,两者算法思想差不多,这里仅介绍至上而下的合并排序。
至上而下的合并是一种典型的分治算法(Divide-and-Conquer),如果两个序列已经排好序了,那么采用合并算法,将这两个序列合并为一个大的序列也就是对大的序列进行了排序。
首先我们将待排序的元素均分为左右两个序列,然后分别对其进去排序,然后对这个排好序的序列进行合并,代码如下:

public class MergeSort<T> where T : IComparable<T>{    private static T[] aux; // 用于排序的辅助数组    public static void Sort(T[] array)    {        aux = new T[array.Length]; // 仅分配一次        Sort(array, 0, array.Length - 1);    }    private static void Sort(T[] array, int lo, int hi)    {        if (lo >= hi) return; //如果下标大于上标,则返回        int mid = lo + (hi - lo) / 2;//平分数组        Sort(array, lo, mid);//循环对左侧元素排序        Sort(array, mid + 1, hi);//循环对右侧元素排序        Merge(array, lo, mid, hi);//对左右排好的序列进行合并    }    ...}
合并排序原理:

这里写图片描述
这里写图片描述

可以看到我们对数组N进行MergeSort的时候,是逐级划分的,这样就形成了一个满二叉树,树的每一及子节点都为N,树的深度即为层数lgN+1,满二叉树的深度的计算可以查阅相关资料,上图中最后一层子节点没有画出来。这样,这棵树有lgN+1层,每一层有N个节点,所以

                         D(N)=(lgN+1)N=NlgN+N=NlgN

这里写图片描述

0 0
原创粉丝点击