对于非递归的快速排序,推荐使用栈,和递归的快速排序都是不断的去调整每次遍历的空间,并通过区间的目标值,一般取区间的第一个值来进行左右区间的划分,再递归调用Partition,和递归不同的是使用栈可以成对的进行管理区间,每次Partition都会都会得到一个目标值,这个目标值和你之前存储在栈中的区间范围可以做判断,当它和你的左区间长度大于2时,则认为可以进行下一次的Partition并入栈,同理当它和你的右区间长度大于2也是如此。因为你每次都是成对的去存储你的区间所以对于每次取也应该成对的把区间取出来,当你的栈为空时则排序完成。
代码如下:
public static void QuickSortNoRecursion(int[]arr, int left, int right) {
Stack<int> partitionRange = new Stack<int>();
if (left < right) {
partitionRange.Push(right); //先进大的数,再进小的数,保存的是范围
partitionRange.Push(left);
while (partitionRange.Count > 0) {
int i = partitionRange.Pop(); //左区间
int j = partitionRange.Pop(); //右区间
int index = Partiton(arr, i, j);
if (index > i + 1) {
partitionRange.Push(index - 1);
partitionRange.Push(i);
}
if (index < j - 1) {
partitionRange.Push(j);
partitionRange.Push(index + 1);
}
}
}
}
//一次Partition 调整当前区间的数 比target大的在它右边,比他小的在它左边
public static int Partiton(int[] arr, int left, int right) {
int target = arr[left];
while (left < right) {
while (left < right && target <= arr[right])
right--;
arr[left] = arr[right];
while (left < right && target >= arr[left])
left++;
arr[right] = arr[left];
}
arr[left] = target;
return left;
}