快速排序 && 寻找第K大(小)的数

参考:https://minenet.me/2016/08/24/quickSort.html

快速排序

利用分治法可将快速排序的分为三步:

  1. 在数据集之中,选择一个元素作为”基准”。
  2. 所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。这个操作称为分区 (partition) 操作,分区操作结束后,基准元素所处的位置就是最终排序后它的位置。
  3. 对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
def quickSort(arr, left, right):
    if left >= right:
        return
    low, high = left, right
    key = arr[low]
    while low < high:
        while low < high and arr[high] >= key:
            high -= 1
        arr[low], arr[high] = arr[high], arr[low]
        while low < high and arr[low] <= key:
            low += 1
        arr[low], arr[high] = arr[high], arr[low]
    quickSort(arr, left, low-1)
    quickSort(arr, low+1, right)

if __name__ == '__main__':
    arr = [4, 5, 2, 1, 5, 8, 3, 2, 6]
    quickSort(arr, 0, len(arr)-1)
    print arr

Java

import java.util.Scanner;

public class Main{
    private void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public void quickSort(int[] arr, int left, int right) {
        if (left >= right) {
            return;
        }
        int key = arr[left], low = left, high = right;
        while (low < high) {
            while (low < high && arr[high] > key) {
                high--;
            }
            swap(arr, low, high);
            while (low < high && arr[low] < key) {
                low++;
            }
            swap(arr, low, high);
        }
        quickSort(arr, left, low-1);
        quickSort(arr, low+1, right);
    }

    public static void main(String[] args) {
        Main mainObj = new Main();
        Scanner in = new Scanner(System.in);
        while(in.hasNext()) {
            int n = Integer.parseInt(in.next());
            int[] a = new int[n];
            for (int i=0; i<n; i++) {
                a[i] = Integer.parseInt(in.next());
            }
            mainObj.quickSort(a, 0, a.length-1);
            System.out.println("Sorted a : ");
            for (int i=0; i<a.length; i++) {
                System.out.print(a[i] + " ");
            }
        }
        in.close();
    }
}

寻找第K大(小)的数

寻找第K小的数:

  1. 快速排序中确定基准值后,将数组分为两部分,基准元素前面的一定小于基准元素。后面的大于基准元素。
  2. 如果基准元素前面的元素个数大于K个,则第K小的数一定在基准元素的前面,没必要进行后面的排序。否则就在后面,没必要前面的排序
  3. 直到这个基准元素的位置刚好是K-1
# 寻找第K小的数
def kNum(arr, k):
    if not arr or k <= 0 or k > len(arr):
        return None
    index = partition(arr, 0, len(arr)-1)
    while k-1 != index:
        if k-1 < index:
            index = partition(arr, 0, index-1)
        else:
            index = partition(arr, index+1, len(arr)-1)
    return arr[k-1]

def partition(arr, low, high):
    key = arr[low]
    while low < high:
        while low < high and arr[high] >= key:
            high -= 1
        arr[low], arr[high] = arr[high], arr[low]
        while low < high and arr[low] <= key:
            low += 1
        arr[low], arr[high] = arr[high], arr[low]
    return low

if __name__ == '__main__':
    arr = [4, 5, 2, 1, 5, 8, 3, 2, 6]
    print kNum(arr,9)
原文地址:https://www.cnblogs.com/renzongxian/p/7465453.html