一、原理解析
快速排序法:
基本思路是,從第一個元素開始,把所有比它大的元素放在它后面,把所有比它小的元素放前面。然后划分它前面和后面的所有元素,分別再做快速排序,直到無法再划分為止。
在以下程序案例中我們使用非遞歸的方式,並借助棧的數據結構實現。(關於棧的基本介紹,請看上一篇:http://www.cnblogs.com/HongYi-Liang/p/7766684.html)
二、程序解析
C語言版本:
源碼:
bool bAirob_QuickSort_int16(int16_t *src,int len) //int16_t { int i ; int j ; int head; int tail; MyStack stack={0}; Stack_Init(&stack,2*len); Stack_push(&stack,len-1); Stack_push(&stack,0); while(Stack_size(&stack)) { Stack_top(&stack,&head); Stack_pop(&stack); Stack_top(&stack,&tail); Stack_pop(&stack); i=head; j=tail; while(i<j) { while(j>i && src[j]>=src[i]) { --j; } Swap(&src[i],&src[j]); while(i<j && src[i]<=src[j]) { ++i; } Swap(&src[i],&src[j]); } if(i!=tail) { Stack_push(&stack,tail); Stack_push(&stack,i+1); } if(i!=head ) { Stack_push(&stack,i-1); Stack_push(&stack,head); } } Stack_Delete(&stack); return true; }
void Swap(int16_t *a,int16_t *b) { int c=*a; *a=*b; *b=c; }
結果 :
測試程序
#define BUFFSIZE 8 int16_t testbuff[BUFFSIZE] = {7,1,6,2,3,5,0,4}; int main() { int i; bAirob_QuickSort_int16(testbuff,BUFFSIZE); for(i=0;i<BUFFSIZE;i++) { printf("%d ",testbuff[i]); } printf("\r\n"); system("pause"); return 1; }
解析:
- 首先聲明了一個棧結構stack用於儲存還還沒排序完成的段落。
- 先把數組頭索引和尾索引壓入棧中。
- 從棧中把取出兩個數數據,第一個作為頭索引,第二個作為尾索引。
- 以數組頭索引的數據為分界把所有小於它的數放在前面,大於它的數放在后面后面。具體做法是while(i<j){}中的一段,最后i,j會重合。
- 如果前半部分仍能繼續分組( i!=head),則把頭索引和i的前一個元素索引壓入棧中。如果后半部分仍能繼續分組(j!=tail),則把i的下一個元素的索引和尾索引壓入棧中。(壓棧時先壓大的索引再壓小的索引)
- 循環上面3-5步,直到棧為空。
用上面程序為例子
原始數組:{7,1,6,2,3,5,0,4}
第一次循環時,所有小於7的數放到了左邊,大於7的數放到了左邊。變成這樣{4,1,6,2,3,5,0,7}
第二次循環,對{4,1,6,2,3,5,0,7},對黃色部分操作,所有大於4的數在右邊,小於4的數在左邊{0,1,3,2,4,5,6,7}。這時候壓入棧中有兩組數據,4左邊一組,4右邊一組。
第三次循環,對{0,1,3,2,4,5,6,7}進行操作,0作為最小的數已經在最左邊了,所以數組不變。
第四次循環,{0,1,3,2,4,5,6,7},對132操作,同上1是最小且在最左邊了,所以不會改變。
第五次循環,{0,1,3,2,4,5,6,7},對32操作,兩個數調換了位置{0,1,2,3,4,5,6,7}。到這一部,4的左邊已經全部處理完了,接下棧中剩下一組數據,4的右邊。
第六次循環{0,1,2,3,4,5,6,7},對56操作,然而他們本身就好了,到這里為止,排序結束。
現在我們再看一次動圖(因為動圖設置沒有數據“0”就用另一個“1”來代替)