常用排序方法的介绍

1 插入排序

1.1 直接插入排序

直接插入排序的基本思想是:把数组a[n]中待排序的n个元素看成一个有序表和一个无序表,排序过程中每次从无序表中取出第一个元素插入到有序表的适当位置,直至无序表变为空表。
直接插入排序,时间复杂度为O(n^2)。
具体代码如下:

void straight_insertion_sort(int a[], const int start, const int end) {
    int tmp;
    int i, j;
    for (i = start + 1; i < end; i++) {
        tmp = a[i];
        for (j = i - 1; tmp < a[j] && j >= start; j--) {
            a[j + 1] = a[j];
        }
        a[j + 1] = tmp;
    }
} 

1.2 折半插入排序

在查找插入位置的时候,如果运用折半查找,则为折半插入排序。其时间复杂度为O(nlog2n)。
具体的代码如下:

void binary_insertion_sort(int a[], const int start, const int end{
    int tmp;
    int i, j, left, right, mid;
    for(i=start+1; i<end;i++){
        tmp=a[i];
        left=start;
        right=i-1;
        while(left<=right){
            mid=(left+right)/2;
            if(tmp<a[mid])
                right=mid-1;
            else
                left=mid+1;
        }
        for(j=i-1;j>=left;j--)
            a[j+1]=a[j];
        a[left]=tmp;
    }
}

1.3 希尔插入排序

希尔排序的基本思想是:将n个元素的序列,按gap=[n/3]+1作为间隔,所有距离为gap的元素放在一个子序列中进行直接插入排序,然后gap=[gap/3]+1缩小,直到gap=1为止。
排序过程如下:

image.png

具体代码如下:

static void shell_insert(int a[], const int start, const int end, const int gap){
    int tmp;
    int i, j;
    for(i=start+gap;i<end;i+=gap){
        tmp=a[i];
        for(j=a-gap;j>=start&&tmp<a[j];j-=gap){
            a[j+gap]=a[j];
        }
        a[j+gap]=tmp;
    }
}

void shell_sort(int a[], const int start, const int end){
    int gap=end-start;
    while(gap>1){
        gap=gap/3+1;
        shell_insert(a, start, end, gap);
    }
}

2 交换排序

2.1 冒泡排序

冒泡排序的基本方法是:设待排序元素序列的元素个数为n,从后向前两两比较相邻元素的值,如果发生逆序(即前一个比后一个大),则交换它们,直到序列比较完。我们称它为一趟冒泡,结果是最小的元素交换到待排序序列的第一个位置,其他元素也都向排序的最终位置移动。下一趟冒泡时前一趟确定的最小元素不参加比较,待排序序列减少一个元素,一趟冒泡的结果又把序列中最小的元素交换到待排序序列的第一个位置。这样最多做n-1 趟冒泡就能把所有元素排好序。

void bubble_sort(int a[], const int start, const int end){
    int tmp;
    int i, j;
    
    for(i=0;i<end;i++){
        for(int j=end-1;j>i;j--){
            if(a[j-1]>a[j]){
                tmp=a[j-1];
                a[j-1]=a[j];
                a[j]=tmp;
            }
        }
    }
}

2.2 快速排序

快速排序的基本思想是任取待排序元素序列中的某个元素(例如取第一个元素)作为基准,按照该元素的关键字大小,将整个元素序列划分为左右两个子序列:左侧子序列中所有元素的关键字都小于基准元素的关键字,右侧子序列中所有元素的关键字都大于或等于基准元素的关键字,基准元素则排在这两个子序列中间(这也是该元素最终应该安放的位置)。然后分别对这两个子序列重复施行上述算法,直到所有的元素都排在相应位置为止。
排序过程如下:

image.png

具体的代码实现如下:

int partition(int a[], const int start, const int end){
    int i=start;
    int j=end-1;
    const int pivot=a[i];

    while(i<j){
        while(i<j&&a[j]>=pivot)
            j--;
        a[i]=a[j];
        while(i<j&&a[i]<=pivot)
            i++;
        a[j]=a[i];
    }
    a[i]=pivot;
    return i;
}
void quick_sort(int a[], const int start, const int end){
    if(start<end-1){
        const int pivot_pos=partition(a, start, end);
        quick_sort(a, start, pivot_pos);
        quick_sort(a, pivot+1, end); 
    }
}

3 选择排序

选择排序的基本思想是:每一趟在后面n-i(i=1, 2, …, n-2) 个元素中选取最小的元素作为有序序列的第i 个元素。

3.1 简单选择排序

简单选择排序也叫直接选择排序,其基本步骤是:

  • 在一组元素a[i] a[n-1] 中选择最小的元素;
  • 若它不是这组元素中的第一个元素,则将它与这组元素的第一个元素对调;
  • 在剩下的a[i+1] a[n-1] 中重复执行以上两步,直到剩余元素只有一个为止。
    具体实现代码如下:
void simple_selection_sort(int a[], const int start, const int end){
    int tmp;
    int i, j, k;
    for(i=start;i<end;i++){
        k=i;
        for(j=i+1;j<end;j++){
            if(a[j]<a[k])
                k=j;
        }
        if(k!=i){
            tmp=a[i];
            a[i]=a[k];
            a[k]=tmp;
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容

  • 排序的基本概念 在计算机程序开发过程中,经常需要一组数据元素(或记录)按某个关键字进行排序,排序完成的序列可用于快...
    Jack921阅读 1,433评论 1 4
  • 总结一下常见的排序算法。 排序分内排序和外排序。内排序:指在排序期间数据对象全部存放在内存的排序。外排序:指在排序...
    jiangliang阅读 1,347评论 0 1
  • 一、 单项选择题(共71题) 对n个元素的序列进行冒泡排序时,最少的比较次数是( )。A. n ...
    貝影阅读 9,079评论 0 10
  • Ba la la la ~ 读者朋友们,你们好啊,又到了冷锋时间,话不多说,发车! 1.冒泡排序(Bub...
    王饱饱阅读 1,798评论 0 7
  • 你在大量的阅读文章,表明你有求知欲想成为更好的自己,如果你没有写作的习惯,请马上开始写作,因为这样你才是真正在阅读...
    LvJack阅读 430评论 1 0