快速排序(遞迴法與迭代法)
阿新 • • 發佈:2019-01-25
用遞迴法:程式碼簡潔,但執行速度很慢;
用迭代法:程式碼略多,但執行速度很快。
本文快速排序方法:
用兩個指標i和j,分別指向傳進來的低位地址和高位地址。去中間的數為基準值。i從左向右移動,碰到比基準值小的數就繼續+1,直至i所指向的數為不小於基準值為止。j從右向左移動,碰到比基準值大的數就繼續-1,直至j所指向的數為不大於基準值為止。此時如果滿足i小於等於j,就交換i和j所指向數的值,然後i+1,j-1。整個迴圈一直到i大於j才結束。這時分別將低地址和j,i和高地址分別傳入這個函式實現遞迴。其中,遞迴返回的條件為低地址大於等於高地址。
如果用迭代的話,就要用到棧的特性。將高低地址分別壓棧儲存。每次迴圈開始時就從棧頂取出,一對高低地址進行排序,迴圈結束時要將兩對高低地址分別壓棧儲存。直至棧中沒有元素為止。
程式碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 50 //棧的大小
int sl[SIZE];
int sr[SIZE];
int sp = 0;
//入棧
int PUSH(int A, int B)
{
sl[sp]=A;
sr[sp]=B;
sp++;
}
//出棧 int POP(int* pl, int* pr) { sp--; *pl = sl[sp]; *pr = sr[sp]; } //迭代法快速排序 void quicksort(int* a,int l,int r) { int i,j,p,t; PUSH(l,r); while(sp){//棧空即跳出迴圈 POP(&l,&r); i = l; j = r; p=a[(i+j)/2];//設定基準值(隨意設定,不一定是中間的數) while(i<=j) { while(a[i]<p) i++; while(a[j]>p) j--; if(i<=j){//交換數 t=a[i]; a[i]=a[j]; a[j]=t; i++; j--; } }
//判斷是否結束(當l=j時,只有一個元素,不需要排序;
//當l>j時,沒有元素。不需要壓棧)
if(l<j)
PUSH(l,j);
if(i<r)
PUSH(i,r);
}
}
//對應的遞迴法快速排序 void sort(int *a, int low, int high) { if(low>=high) return; int t; int p = a[(low+high)/2]; int i = low; int j = high; while(i<=j){ while(a[i]<p) i++; while(a[j]>p) j--; if(i<=j){ t = a[i]; a[i] = a[j]; a[j] = t; i++; j--; } } sort(a,low,j); sort(a,i,high); } int main() { int a[9] = {34, -13, -12, 33, 0, 12, 9, 4, 18}; quicksort(a,0, 8);//兩種排序只用一種即可 // sort(a,0,8); int i; for(i=0; i<9; i++) printf("%d\t", a[i]); printf("\n"); return 0; }
結果: