快速排序原理:分治法,快速排序在每一轮挑选一个基准元素,比它大的在一边,比它小的在另一变,拆解成两部分。双边循环法和单边循环法实现。
package com.algorithm.sort;import java.util.Arrays;/*** 快速排序原理:分治法,快速排序也属于交换排序,快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列* 的另一边,从而把数列拆解成两个部分。基准元素、比基准元素大的元素、比基准元素小的元素 这种思路叫分治法* <p>* 双边循环法:left 和 right 左右两个指针分别指向数列的最左和最右,从right指针开始>=基准元素 向左移动,< 基准元素right停止移动 进行数据交换,* 切换到left指针,如果 <= 基准元素 left指针向右移动,否则left指针停止移动 进行数据交换。* 如果left和right 两个指针重合则将该位置的数据和基准元素进行交换。 实现了左右两侧 分治*/public class FastSort {public static void main(String[] args) {int[] arr = new int[]{4, 4, 6, 5, 3, 2, 8, 1};FastSort.quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}/*** 单边循环分治法* 1. 选定基准元素* 2. mark 指针表示小于基准元素的区域边界* 如果遍历的元素大于基准元素,继续向后遍历。* 如果遍历的元素小于基准元素,把mark指针右移动一位,因为小于基准元素的区域增大了;遍历到的元素和mark指针所在的位置进行交换,遍历到的元素* 归属于小于基准元素的区域。* 最后将基准元素和mark指针所在的位置进行交换,实现了分治** @param arr* @param startIndex* @param endIndex*/private static int partition2(int[] arr, int startIndex, int endIndex) {int pivot = arr[startIndex];int mark = startIndex;for (int i = startIndex + 1; i <= endIndex; i++) {if (arr[i] < pivot){mark++;int temp = arr[mark];arr[mark] = arr[i];arr[i] = temp;}}//基准元素和mark位置交换arr[startIndex] = arr[mark];arr[mark] = pivot;return mark;}public static void quickSort(int[] arr, int startIndex, int endIndex) {if (startIndex >= endIndex) return;//得到基准元素的位置int pivotIndex = partition2(arr, startIndex, endIndex);//根据基准元素分成两部分进行递归排序//小于基准元素的 进行分治排序quickSort(arr, startIndex, pivotIndex - 1);//大于基准元素的 进行分治排序quickSort(arr, pivotIndex + 1, endIndex);}/*** 分治:双边循环法** @param arr* @param startIndex* @param endIndex* @return*/private static int partition(int[] arr, int startIndex, int endIndex) {int pivot = arr[startIndex];int left = startIndex;int right = endIndex;while (left != right) {//控制right指针比较并左移动while (left < right && arr[right] > pivot) {right--;}while (left < right && arr[left] <= pivot) {left++;}//交换元素if (left < right) {int p = arr[left];arr[left] = arr[right];arr[right] = p;}}//指针发生重合arr[startIndex] = arr[left];arr[left] = pivot;//一轮循环结束 返回基准元素的位置return left;}}
