快速排序算法
下文中提到的“指針”並不是C語言語法上的指針!
下文中提到的“指針”並不是C語言語法上的指針!
下文中提到的“指針”並不是C語言語法上的指針!
首先看下面這個例子:
我們取第一個元素為基准元素:
之后,從右邊開始與基准元素挨個比較,如果比基准元素大,右指針往左移,如果比基准元素小,就與左指針指的元素交換(因為左指針永遠停留在一個
空白的值上,不用擔心值被覆蓋)
4的值比5小,所以左右指針的值交換,右指針就變成空的了:
一旦完成交換操作,另一個指針就要開始移動了!
(交換完成后,左指針要立刻右移一下,因為接下來判斷左指針是否右移的條件是元素與基准的比較,交換完成后左指針指向的元素交換前已經比較過了)
左指針開始右移,指向的元素與基准元素比較,比基准小左指針繼續右移,比基准元素大,就與右指針交換
4比5小,左指針右移:
9比5大,與右指針交換:
一旦完成交換操作,另一個指針就要開始移動了!
(交換完成后,右指針要立刻左移一下,因為接下來判斷右指針是否左移的條件是元素與基准的比較,交換完成后右指針指向的元素交換前已經比較過了)
右指針開始左移,第一個元素小於基准
左右指針的值交換:
交換完成左指針應該立刻右移一位:
左指針開始右移
第一個元素0,小於基准,繼續右移
下一個元素4也小於基准,繼續右移
來到元素7,大於基准,指針的值交換:
交換完成后,右指針立刻左移一位:
元素8大於基准,所以右指針繼續左移:
元素4小於基准,交換值:
交換完成,左指針立刻右移一下:
此時左右指針重合,重合位置放入基准元素:
讓后基准元素左面都比他小,右面都比他大,左右兩個子列再套用上述方法,直至排序結束!
通過分析上面的例子,我們知道,快速排序大體分這么幾步:
while(左指針在右指針的左邊)
{
while(右指針指向的元素大於基准)
{
右指針右移
}
//退出了上面這個循環說右指針移動到了一個小於基准的元素下面
將右指針指向的值賦值給左指針指向的值
左指針立刻右移一下
while(左指針指向的元素小於基准元素)
{
左指針右移一位
}
//退出了上面這個循環說明左指針移動到了一個大於基准的元素下面
將左指針指向的值賦值給右指針指向的值
右指針立刻左移一下
}
最后左右指針會重合,重合的位置賦值為基准元素的值;
左子列重復快速排序;
右子列重復快速排序;
運行結果:
源碼如下:
#include<stdio.h> typedef int keytype; //快速排序 void quicksort(keytype k[] , int ArrayLeft , int ArrayRight) { int left = ArrayLeft; int right = ArrayRight; int temp = k[left]; if (left < right) { while (left < right) { while (left < right && k[right] >= temp) { right--; } //if (k[right] < temp) { k[left] = k[right]; left++; } while(left < right && k[left] <= temp) { left++; } //if (k[left] > temp) { k[right] = k[left]; right--; } } k[left] = temp; quicksort(k,ArrayLeft,left-1); quicksort(k,right+1,ArrayRight); } } #define MAX 100 int main() { //讀取一串數字 printf("請輸入一串無序數字:"); int c; int n = 1; keytype k[MAX]; while ((c = getchar())!='\n') { k[n++] = c-'0'; } if (c == '\n') { k[n] = '\0'; } //快速排序 quicksort(k,1,n-1); printf("這串數字從小到大為:"); for (size_t i = 1; i <= n-1; i++) { printf("%d",k[i]); } return 0; }