最近看了一篇文章,介绍递归转非递归的方法,主要是通过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;
}