快速排序(经典快排以及随机快排)
Posted pipipi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序(经典快排以及随机快排)相关的知识,希望对你有一定的参考价值。
快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
首先来了解一下经典快排:
其中就小于等于的区域可以优化一下,小于的放小于区域,等于的放等于区域,大于的放大于区域。可以利用荷兰国旗问题
荷兰国旗问题:
给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。
这就是荷兰国旗问题,大致过程如图:
代码如下
public class Code5_NetherlandsFlag { public static int[] partition(int[] arr, int l, int r, int num) { int less = l - 1; int more = r + 1; while (l < more) { if (arr[l] < num) { swap(arr, ++less, l++); } else if (arr[l] > num) { swap(arr, --more, l); } else { l++; } } return new int[] { less + 1, more - 1 }; } public static void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } }
优化后快排代码为:
public static void quickSort(int[] arr) { if (arr == null || arr.length < 2) { return; } quickSort(arr, 0, arr.length - 1); } public static void quickSort(int[] arr, int l, int r) { if (l < r) { swap(arr, l + (int) (Math.random() * (r - l + 1)), r); int[] p = partition(arr, l, r); quickSort(arr, l, p[0] - 1); quickSort(arr, p[1] + 1, r); } } public static int[] partition(int[] arr, int l, int r) { int less = l - 1; int more = r; while (l < more) { if (arr[l] < arr[r]) { swap(arr, ++less, l++); } else if (arr[l] > arr[r]) { swap(arr, --more, l); } else { l++; } } swap(arr, more, r); return new int[] { less + 1, more }; } public static void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; }
其中swap(arr, l + (int) (Math.random() * (r - l + 1)), r);这一句是为了将快排受数据状态的影响变成一个概率性的,随机的
以上是关于快速排序(经典快排以及随机快排)的主要内容,如果未能解决你的问题,请参考以下文章
8种面试经典!排序详解--选择,插入,希尔,冒泡,堆排,3种快排,快排非递归,归并,归并非递归,计数(图+C语言代码+时间复杂度)