快排的理解:
設要排序的陣列是
a[0]……a[n-1]
,首先任意選取乙個資料(通常選用陣列的第乙個數)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,
這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。
一趟快速排序的演算法是: 1
)設定兩個變數i、
j,排序開始的時候:
i=0,
j=n-1;
2)以第乙個陣列元素作為關鍵資料,賦值給
key,即
key=a[0];
3)從j開始向前搜尋,即由後開始向前搜尋
(j--)
,找到第乙個小於
key的值
a[j]
,將a[j]
和a[i]
互換; 4)從
i開始向後搜尋,即由前開始向後搜尋
(i++)
,找到第乙個大於
key的
a[i]
,將a[i]
和a[j]
互換;
5)重複第3、
4步,直到
i=j;
6)對i(此時i==j)的左右兩側(low,i-1)(i+1,high)分別再次進行快排處理。
其中二者均需要對變數進行交換,變數交換的**如下:
void swapelement(int& a,int& b)
根據上述理解,遞迴形式的快排實現如下:
//遞迴的形式
void quicksortrecursive(int arr,int low,int high){
if(low>=high)return;
int value=arr[low];
int i=low;int j=high;
while(ivalue)j--;//右邊的都大於value
swapelement(arr[j],arr[i]);
while(arr[i]
非遞迴中要想模擬遞迴的形似需要對首尾元素(陣列座標)進行備份,此處和樹的廣度優先遍歷有些類似不過數的廣度優先用的是佇列,
迴圈過程中,快排會不斷對自己進行二次劃分,遞迴本身也是棧的不斷調動,因此此處需要借用棧來儲存下一次需要快排的左右部分
非遞迴的實現形式如下:
//非遞迴的形式
void quicksortnonrecursive(int arr,int length)
{ stacklowhigh;//先存大再存小,取得時候就可以先取小再取大,此處的大小指的是陣列索引
lowhigh.push(length-1);
lowhigh.push(0);
int low, high;
while(!lowhigh.empty())
{low=lowhigh.top();lowhigh.pop();
high=lowhigh.top();lowhigh.pop();
if(low>=high)continue;
int i=low;int j=high;
int value=arr[low];
while(ivalue)j--;//右邊的都大於value
swapelement(arr[j],arr[i]);
while(arr[i]
歸併排序的遞迴形式與非遞迴形式 C 版
歸併排序的核心思想是分治法,即將待排序資料分成多個小塊,對每個小塊進行排序,然後在兩兩合併小塊,最終完成對整體的排序 時間複雜度是nlogn 輸入 25,12,17,21,15,48 結果 遞迴實現 遞迴類似於對此方法的場景再現,即先對整體進行劃分,然後對劃分後的部分進行排序 對遞迴函式的理解可以認...
演算法 歸併演算法的遞迴與非遞迴形式
歸併演算法是將兩個或兩個以上的有序表組合成乙個新的有序表,它的原理是 假設初始序列含有n個記錄,則可以看成是n個有序子串行,兩兩歸併,得到 n 2 個有序子串行,再次歸併 不斷重複直至歸併到長度為n的有序序列,這樣的排序方法稱為2路歸併排序。例項一 遞迴形式的2路歸併演算法 define maxsi...
C 二分查詢的遞迴形式和非遞迴形式
二分查詢,又名折半查詢,在有序陣列中查詢元素的效率很高 缺點就是只能查詢有序表,因此適用於不用頻繁插入刪除的有序表 如果沒有二分查詢,通過遍歷來查詢表中元素的時間複雜度為o n 而二分查詢時間複雜度為o lgn 二分查詢的非遞迴形式 int binaryresearchnonr int arr,in...