快速排序:是一種交換排序,當完全有序時退化為氣泡排序,時間複雜度為o(n^2)。正常情況下為o(nlogn).
非遞迴:其實就是手動利用棧來儲存每次劃分後兩個序列的起始點和終止點。棧非空時獲取棧頂兩個值:起始點和終止點,然後再根據兩個點劃分獲得中軸,將兩個序列中沒劃分完的起始點和終止點入棧。重複這個過程,直到棧為空時完成排序。
void quicksort(int *arr, int low, int high)
if(pos+1 < high)
while(!stk.empty())
if(pos+1 < h)}}}
歸併排序:將兩個或兩個以上的有序表組合乙個新的有序表稱為「歸併」。先使每個子串行有序,再歸併使子串行段有序,最後得到完全有序的序列。
通常是採用遞迴實現,可是如果待排序序列過大,遞迴可能會導致棧溢位。。所以需要了解一下對於歸併排序的非遞迴實現,
演算法思想:我們先假設陣列的每乙個元素是有序的,然後第一次以有序序列長度k為1的進行兩兩序列比較,接著下一次以有序序列長度k為2進行兩兩序列比較,一直這樣直到有序序列長度大於陣列長度時,排序完成。這過程相當於遞迴實現時,先分治後合併中的「後合併」。
實現如下:
#include #include using namespace std;
//將兩個有序序列排序為乙個有序序列
void sort(int *arr, int *tmp, int start, int mid, int end)
else
}if (i <= mid) }
else }
}//一趟歸併排序
void merge(int *arr, int *tmp, int k, int length)
if (i < length - k)//當不夠兩個有序序列歸併時,但如果還剩超過k個元素,也進行歸併排序;
else//否則將剩餘元素複製到中間陣列裡 }
for (int l = 0; l < length; l++)//一趟歸併完成後,將中間陣列的排序結構複製到原陣列,繼續下一趟歸併,直到完全有序 }
void mergesort(int *arr, int length) }}
void print(int *arr, int length)
printf("\n");
}int main()
; mergesort(arr, n);
print(arr, n);
}
遞迴到非遞迴轉換 歸併排序與快排的非遞迴實現
在高階語言中,函式的引數傳遞是由棧來實現的,後呼叫的函式的引數在棧的上部,先呼叫的函式的引數在棧的下部,在實現遞迴函式時,每一次呼叫的引數等資訊都會儲存在棧中,這樣在資料比較在時會出現棧溢位的錯誤,而且反覆呼叫函式,會使效率變的較低,在 中對 萬個數排序,用遞迴的快排花了 而用非遞迴,需要 而我們可...
遞迴和非遞迴實現歸併排序
1 遞迴實現歸併排序 遞迴排序其實也是利用了完全二叉樹的結構形式,所以時間複雜度和logn掛鉤的。具體遞迴版的歸併排序呢,看下面的 public class ms print s mergesort s system.out.println 排序後的陣列 print s public static ...
快排 歸併排序
二 歸併排序 遞迴 分治的思維 分治 確定分界點 我們下面以中間值q l r 1 為分界點,理論上任何點作為分界點都可 調整區間 x 的在左邊,x的在右邊 兩個區間 遞迴 遞迴處理左右兩段 原題鏈結 題目描述 給定你乙個長度為n的整數數列。請你使用快速排序對這個數列按照從小到大進行排序。並將排好序的...