内部排序:归并排序和快速排序

前言  

之所以把归并排序和快速排序放在一起探讨,很明显两者有一些相似之处:这两种排序算法都采用了分治的思想。下面来逐个分析其实现思想。

归并排序

实现思想

归并的含义很明显就是将两个或者两个以上的有序表组合成一个新的有序表。归并排序中一般所用到的是2-路归并排序,即将含有n个元素的序列看成是n个有序的子序列,每个子序列的长度为1,而后两两合并,得到n/2个长度为2或1的有序子序列,再进行两两合并。。。直到最后由两个有序的子序列合并成为一个长度为n的有序序列。2-路归并的核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列。

下面一系列图展示了2-路归并排序的过程:

第一次实现的代码

根据2-路归并操作的思想,站在节省辅助空间的角度上考虑,我写出的归并操作的代码如下:

/*
将有序的arr[start...mid]和有序的arr[mid+1...end]归并为有序的arr[start...end]
*/
void Merge(int *arr,int start,int mid,int end)
{
    int i = start;
    int j = mid+1;
    int k = 0;
    //brr为辅助数组,
    int *brr = (int *)malloc((end-start+1)*sizeof(int));  

    //比较两个有序序列中的元素,将较小的元素插入到brr中
    while(i<=mid && j<=end)
    {
        if(arr[i]<=arr[j])
            brr[k++] = arr[i++];
        else
            brr[k++] = arr[j++];
    }  

    //将arr序列中剩余的元素复制到brr中
    //这两个语句只可能执行其中一个
    while(i<=mid)
        brr[k++] = arr[i++];
    while(j<=end)
        brr[k++] = arr[j++];  

    //将brr中的元素复制到arr中,使arr[start...end]有序
    for(i=0;i<k;i++)
        arr[i+start] = brr[i];  

    //释放brr所占的内存,并将其置为空
    free(brr);
    brr = 0;
}

调用上面的函数,得到的归并排序的代码应该是这样的:

/*
对arr[start...end]内的元素进行归并排序
归并排序后的顺序为从小到大
*/
void MSort(int *arr,int start,int end)
{
    if(start < end)
    {
        int mid = (start+end)/2;
        MSort(arr,start,mid);       //左边递归排序
        MSort(arr,mid+1,end);       //右边递归排序
        Merge(arr,start,mid,end);   //左右序列归并
    }
}
/*
将该排序算法封装起来
*/
void Merge_Sort(int *arr,int len)
{
    MSort(arr,0,len-1);
}

输入任意数组来测试,结果也是正确的。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索int
, 快速排序
, 排序
, 分治法
, 归并排序
, 有序表
, 序列
, 两个
, 归并
, 归并排序sizeof合并链表
, 二路归并排序
, 归并方法
, 有序
思想
,以便于您获取更多的相关知识。

时间: 2024-10-27 11:22:25

内部排序:归并排序和快速排序的相关文章

内部排序算法:快速排序

基本思想 设当前待排序的数组无序区为R[low..high],利用分治法可将快速排序的基本思想描述为: 分解: 在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左.右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(

常用内部排序算法之二:快速排序

前言 快速排序可以说是内部排序算法中的高手,之所以称为快速排序,是因为快速排序算法从整体性能上讲是排序冠军.快速排序算法的思想是:通过一趟快速排序将待排序的记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的记录的关键字小,则可分别对这两部分记录继续进行排序,达到整个记录有序.实现快速排序算法的核心是partition函数,这个函数的主要目的先选取当中的一个关键字(称为枢轴),然后尽可能将他放在一个位置,使得它左边的值都比它小,右边的值比它大. 快速排序算法实现 package com.

内部排序算法的总结

内部排序总结 这篇博文我们简要地总结下各种内部排序方法. 这10种排序算法中,前面7种属于建立在"比较"基础上的排序算法,通过决策树已经证明,任何基于比较进行的排序算法的时 间复杂度不可能再优于O(n*logn).后面3种不是建立在比较的基础上的,因此,可以达到线性运行时间. 下面我们给出各种排序方法的时空复杂度的表格(属于自己总结,有不对的地方,希望大家指正或补充). 返回栏目页:http://www.bianceng.cnhttp://www.bianceng.cn/Program

数据结构内部排序实验报告

问题描述 数据结构内部排序实验报告 一.实验目的 1.掌握排序的有关概念和特点. 2.熟练掌握直接插入排序.希尔排序.冒泡排序.快速排序.简单选择排序.堆排序.归并排序.基数排序等算法的基本思想.. 3.关键字序列有序与无序,对于不同的排序方法有不同的影响,通过该实验进一步加深理解. 二.实验内容 设有关键字序列k={ 12 , 45 , 21 , 12 , 30 , 2 , 68 , 33 },试用各种排序算法进行排序. 三.实验环境 TC或VC++ 四.实验步骤 1.从键盘输入上述8个整数,

基于C++实现的各种内部排序算法汇总_C 语言

提起排序算法相信大家都不陌生,或许很多人已经把它们记得滚瓜烂熟,甚至随时可以写出来.是的,这些都是最基本的算法.这里就把各种内部排序算法总结归纳了一下,包括插入排序(直接插入排序,折半插入排序,希尔排序).交换排序(冒泡排序,快速排序).选择排序(简单选择排序,堆排序).2-路归并排序.(另:至于堆排序算法,前面已经有一篇文章针对堆排序的算法实现做了详细的描述) C++实现代码如下: /*******************************************************

内部排序——希尔插入排序

直接插入排序在时间复杂度上优势不明显.达到O(n2)的水平了,所以需要想办法降低时间复杂度是很有必要的.当记录的排序就是所求的排序时,时间复杂度会大幅下降,为O(n).这是最理想的状态,当顺序刚好是逆序的时候,时间复杂度最大为O(n2).所以记录越是有序,时间复杂度越低.这个和快速排序不同,大家都知道快速排序在有序的情况下效果是很差的吧. 现在的问题是,如何使得记录变得有序,这个也是我们求的最后结果.希尔排序是一种很好的选择,它的原理是使得记录大体上有序,虽然不是所有都有序,但是大体上有序也是很

我的Java开发学习之旅------&amp;gt;Java经典排序算法之快速排序

一.算法思想     快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). (1) 分治法的基本思想     分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题.递归地解这些子问题,然后将这些子问题的解组合为原问题的解. (2)快速排序的基本思想     设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:①分解:      在

内部排序:计数排序、基数排序和桶排序

前言 最后三种排序算法了,由于都不是基于比较的排序,因此这三种排序算法可以以线性时间运行.但是因为限制条件的特殊性,因此应用面没有基于元素比较的排序算法广,但是在很多特定的情况下还是蛮有用途的,而且效率极高. 计数排序 计数排序是建立在这样的前提条件下的:假设n个输入元素的每一个都是0到k区间内的一个整数,其中k为某个整数.因此我们后面所写的程序也只是针对0到k之间的元素进行排序,换句话说,排序元素中不能有负数. 计数排序的基本思想是:对一个输入元素x,先确定所有输入元素中小于x的元素个数,那么

内部排序:插入排序和希尔排序的N种实现

前言 本来想将所有的内部排序总结为一篇博文,但是随着研究的深入,还是放弃了这个念头,斟前酌后,还是觉得分开来写比较好,具体原因,看完本篇博文也就自然明了了. 本篇文章主要探讨插入排序和希尔排序,之所将二者放在一起,很明显,是因为希尔排序是建立在插入排序的基础之上的. 注:以下各排序算法的N种实现方法大部分都是我根据算法思想,自己写出来的,或者是参考其本身的经典实现,我自己都已测试通过,但不敢保证一定都没问题,如果有疑问,欢迎指出. 插入排序 插入排序的思想很简单,它的基本操作就是将一个数据插入到