sql第5天 子查詢
轉自:C++經典排序演算法總結
假設我們現在對“6 1 2 7 9 3 4 5 10 8”這個10個數進行排序。首先在這個序列中隨便找一個數作為基準數(不要被這個名詞嚇到了,就是一個用來參照的數,待會你就知道它用來做啥的了)。為了方便,就讓第一個數6作為基準數吧。接下來,需要將這個序列中所有比基準數大的數放在6的右邊,比基準數小的數放在6的左邊,類似下面這種排列:
3 1 2 5 4 6 9 7 10 8
在初始狀態下,數字6在序列的第1位。我們的目標是將6挪到序列中間的某個位置,假設這個位置是k。現在就需要尋找這個k,並且以第k位為分界點,左邊的數都小於等於6,右邊的數都大於等於6,遞迴對左右兩個區間進行同樣排序即可。想一想,你有辦法可以做到這點嗎?這就是快速排序所解決的問題。
快速排序是C.R.A.Hoare於1962年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法(Divide-and-ConquerMethod)。它的平均時間複雜度為O(nlogn),最壞時間複雜度為O(n^2).
首先上圖:
從圖中我們可以看到:
left指標,right指標,base參照數。
其實思想是蠻簡單的,就是通過第一遍的遍歷(讓left和right指標重合)來找到陣列的切割點。
第一步:首先我們從陣列的left位置取出該數(20)作為基準(base)參照物。(如果是選取隨機的,則找到隨機的哨兵之後,將它與第一個元素交換,開始普通的快排)
第二步:從陣列的right位置向前找,一直找到比(base)小的數,如果找到,將此數賦給left位置(也就是將10賦給20),此時陣列為:10,40,50,10,60,left和right指標分別為前後的10。
第三步:從陣列的left位置向後找,一直找到比(base)大的數,如果找到,將此數賦給right的位置(也就是40賦給10),此時陣列為:10,40,50,40,60,left和right指標分別為前後的40。
第四步:重複“第二,第三“步驟,直到left和right指標重合,最後將(base)放到40的位置,此時陣列值為: 10,20,50,40,60,至此完成一次排序。
第五步:此時20已經潛入到陣列的內部,20的左側一組數都比20小,20的右側作為一組數都比20大,以20為切入點對左右兩邊數按照"第一,第二,第三,第四"步驟進行,最終快排大功告成。
快速排序程式碼如下
#include<iostream> #include<algorithm> #include<ctime> using namespace std; void OutNum(int *nNum, size_t len) { for (size_t i = 0; i < len; i++) cout << nNum[i] << ' '; cout << endl; } void QuickSort(int* nNum, int nLeft, int nRight) { //處理異常資料 if (NULL == nNum || nLeft < 0 || nRight < 0) return; // 遞迴結束條件 if (nLeft >= nRight) return; //防止有序佇列導致快速排序效率降低 srand((unsigned)time(NULL)); int nLen = nRight - nLeft; int nKeyIndex = rand() % (nLen + 1) + nLeft; swap(nNum[nLeft], nNum[nKeyIndex]); int nBase = nNum[nLeft]; int nFlagLeft = nLeft; int nFalgRight = nRight; while (nFlagLeft < nFalgRight) { // 從後往前找,第一個比基準小的數 while (nFlagLeft < nFalgRight && nNum[nFalgRight] >= nBase) { nFalgRight--; } if (nFlagLeft < nFalgRight) { nNum[nFlagLeft] = nNum[nFalgRight]; } // 從前往後找,第一個比基準大的數 while (nFlagLeft < nFalgRight && nNum[nFlagLeft] <= nBase) { nFlagLeft++; } if (nFlagLeft < nFalgRight) { nNum[nFalgRight] = nNum[nFlagLeft]; } } nNum[nFlagLeft] = nBase; // 遞迴呼叫 QuickSort(nNum, nLeft, nFlagLeft - 1); QuickSort(nNum, nFalgRight + 1, nRight); } int main() { //int nNum[10] = {1,7,4,5,3,8,6,9,0,2}; //int nNum[10] = { 0,1,2,3,4,5,6,7,8,9 }; //int nNum[10] = { 0,1,2,3,4,5,6,7,9,8 }; int nNum[20] = { 20,40,50,10,60, 1,7,4,5,3 }; QuickSort(nNum, 0, 9); OutNum(nNum, 10); return 0; }