快排和歸併排序的非遞迴實現

2021-08-22 10:20:22 字數 1388 閱讀 7681

快速排序:是一種交換排序,當完全有序時退化為氣泡排序,時間複雜度為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的整數數列。請你使用快速排序對這個數列按照從小到大進行排序。並將排好序的...