演算法筆記(三)——分治法(快速排序)
阿新 • • 發佈:2019-01-10
參考了網上大神的理解後,自己也嘗試著寫下傳說中的“快速排序”。
大致思路總結為:挖坑填坑+分治法。
舉個例子:我們對陣列a[9]={6,2,4,3,7,1,5,0,8}進行分析。
首先我們拿陣列中的隨機一個數作為基準數(參照物件,也就是要挖的坑),把基準數變成坑(用“X”來表示),然後我們把它和陣列的第一個數位置交;,比如我們拿到的基準數為5,那麼新陣列順序變為
X 2 4 3 7 1 6 0 8
然後我們從最右邊開始找,找到第一個比X小的數,我們找到了0,然後把0賦值給X,(我們不把這兩個數進行交換操作的原因是為了程式碼簡潔並且提高程式效率),這樣0的位置就變成了一個新坑X,記為
0 2 4 3 7 1 6 X 8
然後我們從0的下一個位置開始,找到第一個比X大的數,我們找到7,然後把7賦值給X,然後7的位置變成新坑,記為
0 2 4 3 X 1 6 7 8
然後我們從7的下一個位置開始,找到第一個比X小的數,找到1,把1賦值給X,1變X,記為
0 2 4 3 1 X 6 7 8
然後我們發現1的下一個位置和坑X的位置是一樣的,那麼,我們就把基準數5填到坑X裡。這樣,我們已經把比基準數大的數全部放到了基準數的右邊,比它小的全部放到了左邊;記為
0 2 4 3 1 5 6 7 8
然後我們分別對基準數的左邊和右邊的子陣列再進行挖坑填坑,直到最後的子數組裡只有一個元素。
程式碼如下:
void quick_sort(int a[],int left,int right){ if(left<right){ srand(time(NULL)); int k=left+rand()%(right-left+1); swap(a[k],a[left]); int x=a[left],i=left,j=right; while(i<j){ while(i<j&&a[j]>=x) j--; if(i<j) a[i++]=a[j]; while(i<j&&a[i]<x) i++; if(i<j) a[j--]=a[i]; } a[i]=x; quick_sort(a,left,i-1); quick_sort(a,i+1,right); } }