算法:常见排序

闲来无事 整理下几种常见的比较排序算法。
按照以往风格,Code+Log,帮助各位看官理解及博主本人备忘🤦🏻‍♂️。

导读

本文粗略的给出了几种比较排序的C语言的算法实现,几乎未提及任何思路或讲解,有兴趣的同学请自行拓展。
已完成:冒泡排序、冒泡排序的优化、选择排序、快速排序。
待完成:归并排序、插入排序、堆排序。[拖延症🤦🏻‍♂️]

图片来自百度百科

排序的稳定性是指如果在排序的序列中,存在前后相同的两个元素的话,排序前和排序后它们的相对位置不发生变化。

正文

如无特殊声明,文中示例数组均为:

int arr[] = {2, 0, 6, 1, 9, 5, 4, 7, 8, 3};

另,部分函数中使用到了变量交换宏定义

#define swap(a, b)   (a^=b, b^=a, a^=b)

关于按位异或运算符^,如有之前未了解过的同学欢迎自行百度,或等我有时间再做拓展[拖延症再次🤦🏻‍♂️]。

1. 冒泡排序_1.0

最基础的排序,没有之一。
Code:

void bubbleSort(int *a, int count) {
    for (int i = 0; i < count - 1; i++) {
        for (int j = 0; j < count - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                swap(a[j], a[j+1]);
            }
        }
//        printf("OneStep : i = %d  ", i); //log
//        printArray(a, count);       //log
    }
}

Log:

OriginalArray   :{ 2, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStep : i = 0  { 0, 2, 1, 6, 5, 4, 7, 8, 3, 9 }
OneStep : i = 1  { 0, 1, 2, 5, 4, 6, 7, 3, 8, 9 }
OneStep : i = 2  { 0, 1, 2, 4, 5, 6, 3, 7, 8, 9 }
OneStep : i = 3  { 0, 1, 2, 4, 5, 3, 6, 7, 8, 9 }
OneStep : i = 4  { 0, 1, 2, 4, 3, 5, 6, 7, 8, 9 }
OneStep : i = 5  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
// 此时目标数组已整体有序
OneStep : i = 6  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep : i = 7  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep : i = 8  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
BubbleFinished:  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

2. 冒泡排序_2.0

对冒泡排序常见的改进方法是加入标志性变量flag,用于标志某一趟排序过程中是否有数据交换。
如果进行某一趟排序时并没有进行数据交换,则说明所有数据已经有序,可立即结束排序,避免不必要的比较过程。

Code:

void bubbleSortEx(int *a, int count) {
    bool flag = true;
    for (int i = 0; i < count - 1 && flag; i++) {
        flag = false;
        for (int j = 0; j < count - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                swap(a[j], a[j+1]);
                flag = true;
            }
        }
//        printf("OneStep : i = %d  ", i); //log
//        printArray(a, count);       //log
    }
}

Log:

OriginalArray   :{ 2, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStep : i = 0  { 0, 2, 1, 6, 5, 4, 7, 8, 3, 9 }
OneStep : i = 1  { 0, 1, 2, 5, 4, 6, 7, 3, 8, 9 }
OneStep : i = 2  { 0, 1, 2, 4, 5, 6, 3, 7, 8, 9 }
OneStep : i = 3  { 0, 1, 2, 4, 5, 3, 6, 7, 8, 9 }
OneStep : i = 4  { 0, 1, 2, 4, 3, 5, 6, 7, 8, 9 }
OneStep : i = 5  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
// 此时目标数组已整体有序
OneStep : i = 6  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
BubbleExFinished:{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

3. 选择排序

基本思想:
每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。
Code:

void selectionSort(int *a, int count) {
    int i, j, k;
    for (i = 0; i < count - 1; i++) {
        k = i;
        for (j = i + 1; j < count; j++) {
            if (a[k] > a[j]) {
                k = j;
            }
        }
        if (i != k) {
            swap(a[i], a[k]);
        }
//        printf("OneStep : i = %d  ", i); //log
//        printArray(a, count);       //log
    }
}

Log:

OriginalArray :  { 2, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStep : i = 0  { 0, 2, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStep : i = 1  { 0, 1, 6, 2, 9, 5, 4, 7, 8, 3 }
OneStep : i = 2  { 0, 1, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStep : i = 3  { 0, 1, 2, 3, 9, 5, 4, 7, 8, 6 }
OneStep : i = 4  { 0, 1, 2, 3, 4, 5, 9, 7, 8, 6 }
OneStep : i = 5  { 0, 1, 2, 3, 4, 5, 9, 7, 8, 6 }
OneStep : i = 6  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
// 此时目标数组已整体有序
OneStep : i = 7  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep : i = 8  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
SelectFinished:  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

4. 快速排序

快速排序是对冒泡排序的一种改进方式,通过分治和递归的思想实现。
基本思想:
通过一趟排序将要排序的数据分割成独立的两部分,分割点左边都是比它小的数,右边都是比它大的数。
Code:

void quickSort(int *a, int left, int right) {
    if (left >= right) {
        return;
    }
    int i = left;
    int j = right;
    int key = a[i];
//        printf("OneStepCycle : i = %d, j = %d $", i, j); //log
//        printArray(a, kCount);      //log
    while (i < j) {
        while (i < j && key <= a[j]) {
            j--;
        }
        a[i] = a[j];
//        printf("OneStepCycP1 : i = %d, j = %d $", i, j); //log
//        printArray(a, kCount);      //log
        while (i < j && key >= a[i]) {
            i++;
        }
        a[j] = a[i];
//        printf("OneStepCycP2 : i = %d, j = %d $", i, j); //log
//        printArray(a, kCount);      //log
    }
    a[i] = key;
//    printf("QuickOneStep  : i = %d, j = %d  ", i, j); //log
//    printArray(a, kCount);      //log
    quickSort(a, left, i - 1);
    quickSort(a, i + 1, right);
}

精简Log:

OriginalArray :              { 2, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStep      : i = 2, j = 2  { 1, 0, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStep      : i = 1, j = 1  { 0, 1, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStep      : i = 6, j = 6  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
// 此时目标数组已整体有序
OneStep      : i = 3, j = 3  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 4, j = 4  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 7, j = 7  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 8, j = 8  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
QuickFinished :              { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

分步Log:

OriginalArray :              { 2, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStepCycle : i = 0, j = 9 ${ 2, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStepCycP1 : i = 0, j = 3 ${ 1, 0, 6, 1, 9, 5, 4, 7, 8, 3 }
OneStepCycP2 : i = 2, j = 3 ${ 1, 0, 6, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycP1 : i = 2, j = 2 ${ 1, 0, 6, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycP2 : i = 2, j = 2 ${ 1, 0, 6, 6, 9, 5, 4, 7, 8, 3 }
OneStep      : i = 2, j = 2  { 1, 0, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycle : i = 0, j = 1 ${ 1, 0, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycP1 : i = 0, j = 1 ${ 0, 0, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycP2 : i = 1, j = 1 ${ 0, 0, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStep      : i = 1, j = 1  { 0, 1, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycle : i = 3, j = 9 ${ 0, 1, 2, 6, 9, 5, 4, 7, 8, 3 }
OneStepCycP1 : i = 3, j = 9 ${ 0, 1, 2, 3, 9, 5, 4, 7, 8, 3 }
OneStepCycP2 : i = 4, j = 9 ${ 0, 1, 2, 3, 9, 5, 4, 7, 8, 9 }
OneStepCycP1 : i = 4, j = 6 ${ 0, 1, 2, 3, 4, 5, 4, 7, 8, 9 }
OneStepCycP2 : i = 6, j = 6 ${ 0, 1, 2, 3, 4, 5, 4, 7, 8, 9 }
OneStep      : i = 6, j = 6  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
// 此时目标数组已整体有序
OneStepCycle : i = 3, j = 5 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP1 : i = 3, j = 3 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP2 : i = 3, j = 3 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 3, j = 3  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycle : i = 4, j = 5 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP1 : i = 4, j = 4 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP2 : i = 4, j = 4 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 4, j = 4  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycle : i = 7, j = 9 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP1 : i = 7, j = 7 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP2 : i = 7, j = 7 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 7, j = 7  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycle : i = 8, j = 9 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP1 : i = 8, j = 8 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStepCycP2 : i = 8, j = 8 ${ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
OneStep      : i = 8, j = 8  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
QuickFinished :              { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

以上。

部分图片及表述引自:静默虚空-博客园

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 排序算法经过了很长时间的演变,产生了很多种不同的方法。对于初学者来说,对它们进行整理便于理解记忆显得很重要。每种算...
    DNIX阅读 1,672评论 0 2
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,164评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,727评论 0 15
  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 2,255评论 0 35
  • 看到题目不知道的朋友都蒙了吧,这哪跟哪啊?这又是整的哪一出啊?嘿嘿,还别说,在错中复杂的事物当中,只要我们用心,用...
    正本阅读 440评论 0 3