Kuangcp/JavaBase

View on GitHub
algorithms/src/main/java/com/github/kuangcp/sort/Quick.java

Summary

Maintainability
C
1 day
Test Coverage
package com.github.kuangcp.sort;

import java.util.Arrays;

/**
 * 快速排序
 * 最坏的情况:当数列是一样的数据 O(n^2)
 * 理想:O(n*log n)
 *
 * @author Myth
 */
public enum Quick implements SortAlgorithm {

  INSTANCE;

  @Override
  public int[] sort(int[] data) {
    int[] result = Arrays.copyOf(data, data.length);
    QuickSort sort = new FirstImpl();
    sort.sortData(result, 0, result.length - 1);
    return result;
  }


  interface QuickSort {

    void sortData(int[] data, int low, int high);
  }

  /**
   * 高效的写法
   */
  static class FirstImpl implements QuickSort {

    @Override
    public void sortData(int[] data, int low, int high) {
      if (low >= high) {
        return;
      }

      int lowIndex = low;
      int highIndex = high;

      int value = data[low];
      while (lowIndex < highIndex) {
        // 找出右边小于低位所在的标识值
        while (lowIndex < highIndex && data[highIndex] >= value) {
          highIndex -= 1;
        }
        data[lowIndex] = data[highIndex];

        // 找出左边大于标识值
        while (lowIndex < highIndex && data[lowIndex] <= value) {
          lowIndex += 1;
        }
        data[highIndex] = data[lowIndex];
      }

      data[lowIndex] = value;

      sortData(data, low, lowIndex - 1);
      sortData(data, highIndex + 1, high);
    }
  }

  /**
   * 个人手写
   */
  static class SecondImpl implements QuickSort {

    @Override
    public void sortData(int[] data, int low, int high) {
      int lowIndex = low;
      int highIndex = high;
      int index = data[low];

      while (lowIndex < highIndex) {
        while (lowIndex < highIndex && data[highIndex] >= index) {
          highIndex--;
        }
        if (lowIndex < highIndex) {
          int temp = data[highIndex];
          data[highIndex] = data[lowIndex];
          data[lowIndex] = temp;
          lowIndex++;
        }

        while (lowIndex < highIndex && data[lowIndex] <= index) {
          lowIndex++;
        }
        if (lowIndex < highIndex) {
          int temp = data[highIndex];
          data[highIndex] = data[lowIndex];
          data[lowIndex] = temp;
          highIndex--;
        }
      }

      if (lowIndex > low) {
        sortData(data, low, lowIndex - 1);
      }
      if (highIndex < high) {
        sortData(data, lowIndex + 1, high);
      }
    }
  }

  /**
   * 对象数组排序
   */
  public <T extends Comparable<? super T>> T[] quickSort(T[] data, int start, int end) {
    int low = start + 1, high = end;
    T key = data[start];

    if (start >= end) {
      return (data);
    }

    while (true) {
      while (data[high].compareTo(key) > 0) {
        high--;
      }
      while (data[low].compareTo(key) < 0 && low < high) {
        low++;
      }
      if (low >= high) {
        break;
      }
      if (data[low] == key) {
        high--;
      } else {
        low++;
      }
    }

    if (start < low - 1) {
      this.quickSort(data, start, low - 1);
    }
    if (high + 1 < end) {
      this.quickSort(data, high + 1, end);
    }

    return data;
  }
}