美文网首页
算法:常见排序

算法:常见排序

作者: 乌鸦菌 | 来源:发表于2017-06-18 20:28 被阅读13次

闲来无事 整理下几种常见的比较排序算法。
按照以往风格,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 }

以上。

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

相关文章

  • 数据结构与算法

    常见排序算法 堆排序 算法大全 算法大汇总

  • LeetCode大全

    1.常见排序算法: 常见的排序算法:冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序、堆排序、计数排序、...

  • 排序算法

    常见的排序算法 常见的排序算法有:插入、希尔、选择、冒泡、归并、快速、堆排序。。。 插入排序 算法步骤一、从数组的...

  • Python知识点:常见算法的python实现

    提到排序算法,常见的有如下几种:冒泡排序、选择排序、插入排序、快速排序、堆排序、归并排序、希尔排序;查找算法最常见...

  • 排序算法(四) 希尔排序(插入排序的进化)

    参考Java排序算法(四):希尔排序常见排序算法 - 希尔排序 (Shell Sort) 希尔排序算法是按其设计者...

  • Rust数据结构——排序算法(一)

    Rust数据结构——排序算法(一) 0x01 常见的排序算法 排序算法是数据结构中很常见的算法。如果你了解过数据结...

  • IOS常见算法

    常见算法: 快速排序: 选择排序: 冒泡排序: 测试代码:

  • 常见排序算法

    整理常见排序算法。

  • 开发者应该掌握的几种排序算法

    该篇文章主要介绍了算法基础以及几种常见的排序算法:选择排序、插入排序、冒泡排序、快速排序、堆排序。 一、算法基础 ...

  • 排序算法

    排序算法 排序是最基本的算法之一,常见的排序算法有插入排序、希尔排序、选择排序、冒泡排序、堆排序、归并排序及快速排...

网友评论

      本文标题:算法:常见排序

      本文链接:https://www.haomeiwen.com/subject/dsqwqxtx.html