教你仅用二十行代码完成快速排列,草履虫都能学会!

C语言库函数是把自定义函数放到库里,是别人把一些常用到的函数编完放到一个文件里,供程序员使用。程序员用的时候把它所在的文件名用#include<>加到里面就可以了(尖括号内填写文件名),例如#include<math.h>。我们首先在这里调用两个库:

#include <stdio.h>
#include <stdlib.h>

注意到,题目要求我们对数组进行打印,我曾经详细的介绍了关于数组五种初始化方法,这些初始化方式其实在开发中还是蛮实用的;对于数组元素的访问和修改是通过数组下标的方式来解决的,数组遍历的原理也是一样,通过 while 循环或者 for 循环直接遍历数组下标从而达到访问或者修改数组值的目的;

需要注意的是:

A.数组中每个元素的数据类型必须相同,例如:int a[4],每个元素都必须为 int;
B.数组长度 length 最好是整数或者常量表达式;
C.访问数组元素时,下标的取值范围为 0≤ index < length;
D.数组是一个整体,它的内存是连续的

我们可以轻松的写出这个函数:

void visit(int a[])
{
    for (int k = 0; k < 10; k++)
    {
        printf("%d,", a[k]);
    }
    printf("\n");
}

同时,我们应该设立一个swap函数,以便于交换两个element的位置。

对于C语言中交换两个数的方法,目前大体上有这么5种:

1:直接利用中间变量进行交换;

2:利用指针传入函数地址在函数内部进行利用中间变量交换;

3:将两个需要交换的数进行加减运算进行交换;

   注:因C语言有浮点数之分,不可以认为乘除也可进行交换。

4:将两个数进行亦或运算,也可以实现交换两个数的目的;

5:对两个数进行位操作,也可以实现交换两个数的目的。

我们采取了第一种方式,代码如下:

void swap(int* a1, int* a2){
    int temp = *a2;
    *a2 = *a1;
    *a1 = temp;
    }

于是,我们有了一个朴素的想法,可以使用三个element并且使用它们的中值作为pivot,这一个方法就是我们所熟知的Median-of-Three Partitioning。Typically,我们采取最左端、中间、最右端作为如上三个element,实验表明,大概能节省5%的运行时间。具体代码如下:

int mid3(int a[], int left, int right){int center = (left + right) / 2;if (a[left] > a[right]) swap(&a[left],&a[right]);if (a[left] > a[center]) swap(&a[left],&a[center]);if (a[center] > a[right]) swap(&a[center],&a[right]);swap(&a[center],&a[right-1]);return a[right-1];}

我们意识到,当元素过少时不应该使用快速排序,而是使用插入排序。实验表明,同只采用快速排序一种方法对比,采取该种策略会节省15%的运行时间。插入排序的代码如下:

void insertSort(int a[], int left, int num){int temp, i, j;for (i = 0; i < num; i++){temp = a[left+i];for (j = left+i; j >= 1 && temp < a[j - 1]; j--) a[j] = a[j - 1];a[j] = temp;}printf("insert(%d,%d):", left, num);visit(a);}

此处的函数主要实现递归的方法, 我就不在这里赘述了,比较简洁,代码如下:

void Qsort(int a[], int left, int right){if (left + 3 <= right){int i=left, j=right-1, temp;int pivot = mid3(a, left, right);for (;;){while (a[++i] < pivot){}while (a[--j] > pivot){}if (i < j) swap(&a[i],&a[j]);else break;}swap(&a[i],&a[right - 1]);printf("Qsort(%d,%d):", left, right);visit(a);Qsort(a, left, i - 1);Qsort(a, i + 1, right);}else insertSort(a, left, right-left+1);}

 最后,我们可以轻而易举地将上述函数拼接至main函数中,完成快速排序(quick sort)。

int main(){int index;scanf("%d", &index);int a[10] = {49, 38, 65, 97, 76, 13, 27, 50, 2, 8};int i=-1, j=9;int pivot = a[index];swap(&a[index],&a[9]);for ( ; ; ){while (a[++i] < pivot){}while (a[--j] > pivot){}if (i < j){swap(&a[i],&a[j]);}else break;}swap(&a[i],&a[9]);printf("Qsort(0,9):");visit(a);Qsort(a, 0, i - 1);Qsort(a, i + 1, 9);return 0;}

参考文献:

[1]严蔚敏,吴伟民.数据结构[M].清华大学出版社.

[2]王路群.数据结构[M].中国水利水电出版社.

[3]吉书鹏.操作系统[M].大连理工大学出版社.

[4] Zhihao Han:Quick sort is all you need. published on JSTF 2022.(Journal of Six Two Five)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值