hymn

忽有故人心头过,回首山河已是秋。

  menu
132 文章
0 浏览
4 当前访客
ღゝ◡╹)ノ❤️

快排

快速排序:

在每一轮挑选一个基准元素,并让其他比他大的移动到一边,比他小的移动到另一边,从而把数组拆解成两个部分。这种思路叫做分治法。

时间复杂度:O(nlogn)

package sort;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * @author: daixyhymn
 * @description: 快排
 * @date: 2020/11/4 14:50
 */
public class QuickSort {

  /**
   * 快排
   * @param array
   * @param startIndex
   * @param endIndex
   */
  public static void quickSort(int[] array, int startIndex, int endIndex){
    // 递归条件结束: startIndex 大于 endIndex
    if (startIndex >= endIndex) {
      return;
    }
    // 得到基准元素,分成两部分进行递归
    int pivotIndex = partition2(array, startIndex, endIndex);

    // 根据基准元素,分成两部分进行递归
    quickSort(array, startIndex, pivotIndex - 1);
    quickSort(array, pivotIndex + 1, endIndex);
  }

  /**
   * 用栈的形式
   * @param array
   * @param startIndex
   * @param endIndex
   */
  public static void quickSortStack(int[] array, int startIndex, int endIndex){
    // 用一个集合栈来代替递归的函数栈
    Stack<Map<String, Integer>> quickStack = new Stack<>();
    // 整个数列的气质下标,以哈希的形式入栈
    Map rootParam = new HashMap();
    rootParam.put("startIndex", startIndex);
    rootParam.put("endIndex", endIndex);
    quickStack.push(rootParam);

    // 循环结束条件:栈为空时
    while (!quickStack.isEmpty()) {
      // 栈顶出栈,得到起止下标
      Map<String, Integer> param = quickStack.pop();
      // 得到基准元素位置
      int pivotIndex = partition(array, param.get("startIndex"), param.get("endIndex"));

      // 根据基准元素位置分成两个部分,把每一部分的起止下标入栈
      if (param.get("startIndex") < pivotIndex -1) {
        Map<String, Integer> leftParam = new HashMap<>();
        leftParam.put("startIndex", param.get("startIndex"));
        leftParam.put("endIndex", pivotIndex -1);
        quickStack.push(leftParam);
      }

      if (pivotIndex + 1 <  param.get("endIndex")) {
        Map<String, Integer> rightParam = new HashMap<>();
        rightParam.put("startIndex", pivotIndex + 1);
        rightParam.put("endIndex", param.get("endIndex"));
        quickStack.push(rightParam);
      }
    }
  }

  /**
   * 双边循环法
   * @param array
   * @param startIndex
   * @param endIndex
   * @return
   */
  public static int partition2(int[] array, int startIndex, int endIndex){
    // 取第一个 位置(也可以随机位置)的元素作为基准元素
    int pivot = array[startIndex];
    int left = startIndex;
    int right = endIndex;

    while (left < right) {
      while (left < right && array[right] > pivot) {
        right--;
      }
      while (left < right && array[left] <= pivot) {
        left++;
      }
      if (left < right) {
        int p = array[left];
        array[left] = array[right];
        array[right] = p;
      }
    }
    // pivot 和指针重合点交换
    array[startIndex] = array[left];
    array[left] = pivot;

    return left;
  }

  /**
   * 单边循环法
   * @param array
   * @param startIndex
   * @param endIndex
   * @return
   */
  public static int partition(int[] array, int startIndex, int endIndex){
    int pivot = array[startIndex];
    int mark = startIndex;

    for (int i = startIndex + 1; i <= endIndex; i++) {
      if (array[i] < pivot) {
        mark++;
        int p = array[mark];
        array[mark] = array[i];
        array[i] = p;
      }
    }
    array[startIndex] = array[mark];
    array[mark] = pivot;
    return mark;
  }

  public static void main(String[] args) {
    int[] array = new int[]{4,5,1,6,5,9,2,0};
    quickSortStack(array, 0, array.length -1);
    System.out.println(Arrays.toString(array));
  }
}


标题:快排
作者:hymn
地址:https://dxyhymn.com/articles/2020/11/04/1604475576534.html