最近看了一篇文章,介紹遞迴轉非遞迴的方法,主要是通過stack的資料結構類比遞迴函式堆棧的層次調用(後進先出,最裡層-->最外層,層層彈出),排序演算法很多是通過遞迴來實現的,這裡照葫蘆畫瓢,實現一下非遞迴的快排演算法。
先附上快排的遞迴用法,用於對比
/* 快速排序:從數組中選出一個值flag,通過一輪比較,將比flag大的置於一側,比flag小的置於另一側,再依照此法,對這兩部分做同樣的比較 *//* 複雜度:最壞情況,每次選取flag為最大或最小元素,退化成線性比較,O(n^2) 最好情況,每次選取的flag為中間值時,類似平衡樹,每次都對半分,效能為O(nlogn) */void Test_Init::quickSort(std::vector<int>& sortArray, int begin, int end){if (begin >= end){return;}int i = begin;int j = end;int flag = sortArray[j];//標誌位,以flag為界限,大於flag置於右邊,小於flag的置於左邊while(i < j){while ((sortArray[i] <= flag) && ((i < j))){i++;}sortArray[j] = sortArray[i];while((sortArray[j] >= flag)&& (i < j)){j--;}sortArray[i] = sortArray[j]; }sortArray[i]=flag;/* 經過一輪比較,以flag為界限,分為左右兩邊,左邊比flag小,右邊比flag大然後遞迴進行下一輪比較 */quickSort(sortArray, begin, i - 1);quickSort(sortArray, i + 1, end);}
再看一下非遞迴的寫法
void Test_Init::quickSortNoRecursive(std::vector<int>& sortArray){struct SnapShot{int start;int end;};SnapShot shot;shot.start = 0;shot.end = sortArray.size() - 1;std::stack<SnapShot> shotStack;shotStack.push(shot);while(!shotStack.empty()){/* 每次彈出棧頂元素 */SnapShot cur = shotStack.top();shotStack.pop();if (cur.start >= cur.end){/* 僅有一個元素時,不必比較 */continue;}int i = cur.start;int j = cur.end;int flag = sortArray[j];while(i < j){while ((sortArray[i] <= flag) && ((i < j))){i++;}sortArray[j] = sortArray[i];while((sortArray[j] >= flag)&& (i < j)){j--;}sortArray[i] = sortArray[j]; }/* flag右側進棧 */sortArray[i]=flag;int tmp = cur.start;cur.start = j + 1;shotStack.push(cur);/* flag左側進棧,先出 */SnapShot next;next.end = j - 1;next.start = tmp;shotStack.push(next);}return;}