排序之分治排序

  本算法是笔者研读算法导论分治内容伪代码所写,俗话说,它山之石,可以攻玉。算导对排序有非常详细的解释,而分治排序更是其中巧妙的一种排序算法。分治排序先把数组分成[l,mid]与(mid,r]两部分,多次划分直到每个部分只有1个元素。然后把这两部分进行比较排序。(由于上一次的排序,这两个分数组内部是有序的);

  举例说数组:[7,3,5,4,6,2,1],定义INF = 100,大于数组每个元素

    (1)、第一次划分 [7,3,5,4] , [6,2,1]

    (2)、对[7,3,5,4]进行第二次划分 [7,3],[5,4]

    (3)、对[7,3]划分[7],[3];

(4)元素只有一个后,返回到[7,3],依次比较两个部分里的数进行排序。[7],[3]比较排序后,[3,7]

       (5)同理[5,4]排完后为[4,5];返回到[7,3,5,4],由于上一步排序,该数组为[3,7,4,5];3跟4比,3小,[3,...],7跟4比,4小,[3,4,...],7跟5比,5小[3,4,5,..],7跟INF比,7小,[3,4,5,7];其实两个分数组都有一个INF元素在末尾.([3,7,INF],[4,5,INF]);

(6)同理向上合并,最后得到结果

  简而言之,分治排序就是先把数组不到二分,直到只剩下一个元素。然后向上合并进行比较排序。比较排序比较巧妙的地方在于增加了一个INF,方便比较。

#include<iostream>
using namespace std;
#define INF (100)
//INF 为大于等于待排序数的一个数字

void mSort_part(int* a,int l,int mid,int r)
{
    int len1,len2,i,j,k;
    len1 = mid - l + 2;
    len2 = r - mid + 1;
    //数组A的范围是[l,mid]并且加上一个INF数字.
    //数组B的范围是[mid+1,r],并且加上一个INF数字.
    int A[len1],B[len2];
    k = l;
    for(i=0;i<len1-1;++i)
        A[i] = a[k++];
    A[i] = INF;
    for(j=0;j<len2-1;++j)
        B[j] = a[k++];
    B[j] = INF;
    i = j = 0;
    for(k=l;k<=r;++k)
        if(A[i] < B[j])
            a[k] = A[i++];
        else
            a[k] = B[j++];
}

//分治
void mSort(int *a,int l,int r)
{
    if(l < r)
    {
        int mid = (l+r)/2;
        //先分
        mSort(a,l,mid);
        mSort(a,mid+1,r);
        //最后进行合并排序
        mSort_part(a,l,mid,r);
    }
}

int main()
{
    //test code
    int a[] = {7,10,9,2,6,8,5,1,4,3};
    int n = sizeof(a) / sizeof(int);
    mSort(a,0,n-1);
    for(int i=0;i<n;++i)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}
            
时间: 2024-10-21 09:02:28

排序之分治排序的相关文章

XJOI NOIP2015模拟赛Day1 T2 ctps bitset优化 或 排序+cdq分治+树状数组+平衡树

题意: 4维空间中有1个点集A,|A|=n,用(a,b,c,d)表示每个点. 共有m个询问,每次询问输入一个点(a,b,c,d),求最大的S,其中S={p|p∈A且ap<=a,bp<=b,cp<=c,dp<=d},输出|S| 输入格式: 第一行n 接下来n行有n个4维点对 第n+2行有一个数m 再接下来m行每行有一个四维点对,表示每个询问 输出格式: 对于每个询问输出一个数 **方法:**bitset优化 或 排序+cdq分治+树状数组+平衡树 解析: 神题,考场不会,暴力骗40,

九种经典排序算法详解(冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序,计数排序,桶排序,基数排序)

综述 最近复习了各种排序算法,记录了一下学习总结和心得,希望对大家能有所帮助.本文介绍了冒泡排序.插入排序.选择排序.快速排序.归并排序.堆排序.计数排序.桶排序.基数排序9种经典的排序算法.针对每种排序算法分析了算法的主要思路,每个算法都附上了伪代码和C++实现. 算法分类 原地排序(in-place):没有使用辅助数据结构来存储中间结果的排序**算法. 非原地排序(not-in-place / out-of-place):使用了辅助数据结构来存储中间结果的排序算法 稳定排序:数列值(key)

冒泡排序,快速排序,归并排序,插入排序,希尔排序,堆排序,计数排序,桶排序,基数排序

选择排序,冒泡排序,快速排序,归并排序,插入排序,希尔排序,计数排序,桶排序,基数排序 以上是一些常用的排序算法. 选择排序 for(int i = 0; i < n; i++) { int minval = a[i]; int minid = i; for (int j = i+1; j < n; j++) { if (a[j] < minval) { minid = j; minval = a[j]; } } swap(a[i], a[minid]); } 最简单的就是选择排序,就是

【算法】计数排序、桶排序和基数排序详解

01.计数排序.桶排序与基数排序 并不是所有的排序 都是基于比较的,计数排序和基数排序就不是.基于比较排序的排序方法,其复杂度无法突破\(n\log{n}\) 的下限,但是 计数排序 桶排序 和基数排序是分布排序,他们是可以突破这个下限达到O(n)的的复杂度的. 1. 计数排序 概念 计数排序是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,使用 C[i] 来计算 i 出现的次数.然后根据数C来将原数组A中的元素排到正确的位置. 复杂度 计数排序的最坏时间复杂度.最好时间复杂度.平均时

排序算法——希尔排序

希尔排序 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 该方法因DL.Shell于1959年提出而得名. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多, 当增量减至1时,整个文件恰被分成一组,算法便终止. 代码实现 void shellsort(int a[],int n) { int gap=0,i=0,temp=0,j=0; for(

基数排序与桶排序,计数排序【详解】

桶排序简单入门篇^-^ 在我们生活的这个世界中到处都是被排序过的东东.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东东都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的是我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个同学分别考了5分.3分.5分.2分和8分,哎,考得真是惨不忍睹(满分是10分).接下来将分

C言语合并排序(兼并排序)算法及代码

合并排序也称兼并排序,其算法思惟是将待排序序列分为两局部,顺次对分得的两个局部再次运用合并排序,之后再对其停止兼并.仅从算法思惟上理解合并排序会认为很笼统,接下来就以对序列A[0], A[l]-, A[n-1]停止升序陈列来停止解说,在此采取自顶向下的完成办法,操作步调如下.(1)将所要停止的排序序列分为阁下两个局部,假如要停止排序的序列的肇端元素下标为first,最初一个元素的下标为last,那么阁下两局部之间的临界点下标mid=(first+last)/2,这两局部辨别是A[first -

ArcGIS10.1 属性值排序,图斑排序

ArcGIS10.1技术交流(第4期) 属性值排序,图斑排序 第一讲 介绍了arcgis10.1中的排序这一个工具,介绍了如何利用这一个工具对属性值进行排序,以及对图斑块进行一个空间排序,以及途中还介绍了一下目前网上一种比较普通方法来进行图斑排序的一个原理,再次粗略的引了一下皮亚诺曲线 点击学习 第二讲 为上一讲讲到的ArcGIs自带的排序工具的下承接(),介绍从提取图斑外接矩形的左上点坐标,导出至Excel,对得到的坐标值进行两个排序,得到一个排序值,但是重点呢,不是结果,而是告诉大家这种方法

C语言中的排序算法--冒泡排序,选择排序,希尔排序

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端 维基百科:点击打开链接 [cpp] view plain copy /* 用选择法对10个数进行排序 */ #include<stdio.h> void main() { int i,j,