快速排序算法网上也有很多介绍,这里不再对原理进行过多的说明,直接进入实战编码并理解记忆。
编码时首先需要准备几个变量:
- 交换时使用的中间变量——tem
- 交换时始终是头和尾进行交换,指向头和尾的指针——*pStart, *pEnd
- 基础值,初始值一般是数组的第一个数——base
还没有开始比较交换时,基数就是pStart(头)所指向的数。
经过第一次比较后,如果进行交换,基数则是pEnd(尾)指向的数,同时将pStart++(头后移一位);如果没有交换,基数则是pStart指向的数,同时将pEnd–(尾前移一位)。
再进行后续的比较,比较后的操作一样…
反复如上操作,当pStart与pEnd相等停止操作。
这时可以发现三个现象:
- 基数所在位置的指针不变;
- pStart和pEnd在同一个数的位置,这个数是基数,并将数组分成两个数组;
- 如是从小到大的排序写法,那么基数左边的数组全部比基数小,右边全部比基数大。
然后将分割出来的两个数组再次进入本函数进行递归,退出条件是输入数组元素个数小于等于1
函数代码如下:
typedef int mtdata;
int QuickSort(mtdata *arr, int size)
{
mtdata tem = 0; // 交换时使用的中间变量
// 头指针和尾指针
mtdata *pStart = arr, *pEnd = arr + size - 1;
mtdata base = arr[0]; // 基础值,初始化为数组第一个数
// 退出条件是输入数组元素个数小于等于1
if (size <= 1){
return 0;
}
// 循环操作,当pStart与pEnd相等停止操作
while (pStart < pEnd){
// 头和尾的数进行比较
if (*pStart > *pEnd){
tem = *pStart;
*pStart = *pEnd;
*pEnd = tem;
}
// 判断基数所在的位置
if (base == *pStart){
pEnd--;
}else{
pStart++;
}
}
// 递归处理被分割处理的数组,注意数组元素个数的计算
QuickSort(arr, pStart - arr);
QuickSort(pStart + 1, arr + size - pStart - 1);
return 0;
}
测试代码如下:
#include <stdio.h>
typedef int mtdata;
int QuickSort(mtdata *arr, int size);
int main(void)
{
mtdata arr[7] = { 1, 6, 4, 2, 5, 6, 7 };
QuickSort(arr, 7);
for (int i = 0; i < 7; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
getchar();
return 0;
}