排序算法中很重要的快速排序
递归实现方式
递归实现方式的不同在于分区函数的不同
public static void quickSort(int[] arr, int startIndex, int endIndex) {
if (startIndex >= endIndex) {
return;
}
//分区函数获取基准元素位置
int pivotIndex = singleParition(arr, startIndex, endIndex);
//分治递归
quickSort(arr, startIndex, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, endIndex);
}
- 双向循环指针式,原理是利用左右指针分别维护较大数以及较小数区间
private static int partition(int[] arr, int startIndex, int endIndex) {
int pivot = arr[startIndex]; //使用第一个值作为基准值
int left = startIndex; //左指针
int right = endIndex; //右指针
//当两指针不重合时循环
while (left != right) {
//当右指针大于基准值的时候指针左移
while (left < right && arr[right] > pivot) {
right--;
}
//当左指针小于基准值的时候指针右移
while (left < right && arr[left] <= pivot) {
left++;
}
//交换左右指针
if (left < right) {
swap(arr, left, right);
}
}
//交换基准元素值和左/右指针
arr[startIndex] = arr[left];
arr[left] = pivot;
return left;
}
- 单项循环指针式,使用单指针来区分较大和较小区域
//单边循环分边函数,从小到大依次遍历,若小于基准值,则mark指针向右移动,
//并且让移动后的mark指针当前遍历值互换,最后遍历结束互换mark和基准指针值,并返回mark指针位置
private static int singleParition(int[] arr, int startIndex, int endIndex) {
int pivot = arr[startIndex];
int mark = startIndex;
for (int i = startIndex; i <= endIndex; i++) {
//若值比基准指针小则mark指针左移然后和该值交换
if (arr[i] < pivot) {
swap(arr, i, ++mark);
}
}
//交换mark指针的基准值
arr[startIndex] = arr[mark];
arr[mark] = pivot;
return mark;
}
非递归实现方式
非递归实现方式主要借用了栈的数据结构,来完成递归操作,这里的分区函数和递归的一致
public static void nonRecursiveQuickSort(int[] arr, int startIndex, int endIndex) {
//初始化栈
Stack