快速排序C語言實現與分析
快速排序是C.A.R.Hoare於1962年發明的。
算法的基本思想是:遞歸。
對於一個給定的數組,從中任意選取一個元素,以這個元素爲界,
將其餘元素劃分爲兩個子集,一個子集要求全部小於這個元素,另一個子集要求全部
大於或等於這個元素。對這兩個子集遞歸執行這個過程,當某個子集中的元素個數
小於2時,終止遞歸。
1.算法分析
遞歸思想在C語言程序設計中,比較獨特,並不推薦使用,但其能產生十分緊湊的代碼
。各個大廠,百度,阿里,騰訊等均鍾情於快速排序,可見這個算法的不平庸之處。
在數組排序時,任意選取一個元素,一般選取第一個元素。將數組分成兩個子集,
以這個元素爲界,左邊的子集小於這個元素,右邊的子集大於這個元素。如何實現
這個設想呢?很簡單了,只需要把每一個元素都與這個元素比較一下,小於這個元
素的“依次”排在左邊,大於等於的元素自然就拍到了右邊。然後左邊的子集調用
一次該函數,右邊的子集調用一下該函數。
2.函數實現
在排序過程中,需要頻繁比較和調換數組內兩個元素的位置,
我們這裏設計一個交換兩個元素的函數,十分簡單。
調用該函數能夠交換arry數組中,位置i和位置j的兩個元素。
i和j是數組內任意的下標。
void swap(uint16_t *arry, uint8_t i, uint8_t j)
{
uint16_t temp;
temp = *(arry + i);
*(arry + i) = *(arry + j);
*(arry + j) = temp;
}
排序過程,如下代碼:
int sortq(uint16_t *arry, int left, int right)
{
uint16_t temp;
int i;
if (left >= right) {
return -1;
}
temp = left;
for (i = left + 1; i <= right; i++) {
if (arry[i] < arry[left]) {
swap(arry, ++temp, i);
}
}
swap(arry, left, temp);
sortq(arry, left, temp-1);
sortq(arry, temp+1, right);
}
主函數中,直接調用該函數,實現如下:
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
int main(int argc, const char *argv[])
{
uint16_t data[10] = {23,1,4,7,8,23,9,0,2,2};
int data_len = 10;
sortq(data, 0, 9);
printf("data is:");
while (data_len-- > 0) {
printf("%x\t",data[data_len]);
}
printf("\n");
return 0;
}
3.總結分析
快速排序函數選取數組第一個元素作爲排序分界元素,
然後用第二個元素到最後一個元素,依次與分界元素比較
如果找到任意一個小於分界元素的對象,則將這個對象從第二個
位置開始交換,每找到一個對象,就交換一下,於是有了++temp
操作。temp是小於分界元素的最後一個對象。而不是第一個大於
等於分界元素的對象。這一點跟滿空棧概念一致。經過一輪交換
後,遞歸調用左右子集的交換,直到小於2個元素的子集出現,
則終止該子集。
該算法選取分界元素時,當選取到最小或者最大的元素時,會
花費最常的時間,等於其他算法。所以存在不確定性。
其效率是:O(N*logN) 在所有相同效率模型的算法中,其效率
最高。