前言:我将持续输出对你有用文章,欢迎关注!
查尔斯·安东尼·理查德·霍尔爵士,昵称东尼·霍尔
快速排序 (Quick Sort)是由 图灵奖 得主东尼·霍尔( Tony Hoare )所提出的一种排序算法。在平均状况下,排序 n 个元素要 次比较。在最坏状况下则需要 次比较,但这种状况并不常见。
快速排序使用 分治法 (Divide and conquer)策略来把一个列表(list)分为两个子列表(sub-lists),然后递归地排序两个子列表。
“快速排序”只是一个名字而已,以后会有人取“最快排序”吗?不过,目前 快速排序算法 通常比其他 算法更快,原因请看 《哪种排序算法最快》。
JavaScript 语言实例
Python 语言实例
Go 语言实例
Java 语言实例
PHP 语言实例
C 语言实例
C++ 语言实例
C# 语言实例
Ruby 语言实例
Swift 语言实例
Objective-C 语言实例
Shell 语言实例
1. 算法步骤
- 挑选基准值 :从数列中挑出一个元素(一般会挑选最左边的元素),称为 “基准”(pivot);
- 分区 :对该数列每个元素,比基准值小的放在基准前面,比基准值大的摆在基准的后面(相等的可以到任一边)。遍历完所有元素时,将基准(pivot)移至两个子数列之间。这个过程称为分区( partition )操作;
- 递归排序子数列 :递归地(recursive)对第2步得到的两个子数列进行分区操作;
递归到最后,子数列元素为0个或1个,即这个子数列已经被排序好了,此时退出递归。
2. 动图演示
快速排序动图演示
先看下面的颜色说明会更容易理解上面的动图:
黄色 为当前的基准值
橙色 为已排序好的元素
绿色 为比基准值小的元素
紫色 为比基准值大的元素
红色 表示当前正比较的元素
蓝色 表示待比较的元素
各语言实例
JavaScript
function quickSort(arr, left, right) {
var len = arr.length,
partitionIndex,
left = typeof left != ' number ' ? 0 : left,
right = typeof right != 'number' ? len - : right;
if (left < right) {
partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex-);
quickSort(arr, partitionIndex+, right);
}
return arr;
}
function partition(arr, left ,right) { // 分区操作
var pivot = left, // 设定基准值(pivot)
index = pivot +;
for (var i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
//虽然这里i可能会等于index,对自身没必要移动,但没必要加判断,因为加了判断,所有要移动的都要判断,从而带来更大的负担
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index -);
return index-;
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//第二种方法
function partition(arr, low, high) {
let pivot = arr[low];
while (low < high) {
while (low < high && arr[high] > pivot) {
--high;
}
arr[low] = arr[high];
while (low < high && arr[low] <= pivot) {
++low;
}
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
}
function quickSort(arr, low, high) {
if (low < high) {
let pivot = partition(arr, low, high);
quickSort(arr, low, pivot - 1);
quickSort(arr, pivot + 1, high);
}
return arr;
}
Python
def quickSort(arr, left=None, right=None):
left = if not isinstance (left,(int, float)) else left
right = len(arr)- if not isinstance(right,(int, float)) else right
if left < right :
partitionIndex = partition(arr, left, right)
quickSort(arr, left, partitionIndex-)
quickSort(arr, partitionIndex+, right)
return arr
def partition(arr, left, right):
pivot = left
index = pivot+
i = index
while i <= right:
if arr[i] < arr[pivot]:
swap(arr, i, index)
index+=
i+=
swap(arr,pivot,index-)
return index-
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
Go
func quickSort(arr []int) []int {
return _quickSort(arr,, len(arr)-1)
}
func _quickSort(arr []int, left, right int) []int {
if left < right {
partitionIndex := partition(arr, left, right)
_quickSort(arr, left, partitionIndex-)
_quickSort(arr, partitionIndex+, right)
}
return arr
}
func partition(arr []int, left, right int) int {
pivot := left
index := pivot +
for i := index; i <= right; i++ {
if arr[i] < arr[pivot] {
swap(arr, i, index)
index +=
}
}
swap(arr, pivot, index-)
return index -
}
func swap(arr []int, i, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
Java
public class QuickSort implements IArraySort {
@ Override
public int[] sort(int[] sourceArray) throws Exception {
// 对 arr 进行拷贝,不改变参数内容
int[] arr = Arrays. copy Of(sourceArray, sourceArray.length);
return quickSort(arr,, arr.length - 1);
}
private int[] quickSort(int[] arr, int left, int right) {
if (left < right) {
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex -);
quickSort(arr, partitionIndex +, right);
}
return arr;
}
private int partition(int[] arr, int left, int right) {
// 设定基准值(pivot)
int pivot = left;
int index = pivot +;
for (int i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index -);
return index -;
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
PHP
function quickSort($arr)
{
if (count($arr) <=)
return $arr;
$middle = $arr[];
$leftArray = array();
$rightArray = array();
for ($i =; $i < count($arr); $i++) {
if ($arr[$i] > $middle)
$rightArray[] = $arr[$i];
else
$leftArray[] = $arr[$i];
}
$leftArray = quickSort($leftArray);
$leftArray[] = $middle;
$rightArray = quickSort($rightArray);
return array_merge($leftArray, $rightArray);
}
C
// 基本双向快速排序
void QuickSort(int *A, int start, int end)
{
if(start<end){ // 调试时少了这一步,一直报错
int i=start, j=end;
int pivot = A[i]; // 第个元素作为基准数
while(i<j)
{
while(i<j && A[j]>pivot) j--;
A[i] = A[j];
while(i<j && A[i]<pivot) i++;
A[j] = A[i];
}
A[i] = pivot; // 基准数归位,i左边为较小数,右边为较大数
QuickSort(A, start, i-); // 递归调用,将剩下两部分继续进行快排
QuickSort(A, i+, end);
}
}
C++
// 严蔚敏 《数据结构》标准分割函数
Paritition(int A[], int low, int high) {
int pivot = A[low];
while (low < high) {
while (low < high && A[high] >= pivot) {
--high;
}
A[low] = A[high];
while (low < high && A[low] <= pivot) {
++low;
}
A[high] = A[low];
}
A[low] = pivot;
return low;
}
void QuickSort(int A[], int low, int high) //快排母函数
{
if (low < high) {
int pivot = Paritition(A, low, high);
QuickSort(A, low, pivot -);
QuickSort(A, pivot +, high);
}
}
C#
static void Main(string[] args)
{
Console. Write Line("请输入待排序数列(以","分割):");
string _s = Console.ReadLine();
string[] _sArray = _s.Split(",".ToCharArray());
int _nLength = _sArray.Length;
int[] _nArray = new int[_nLength];
for (int i =; i < _nLength; i++)
{
_nArray[i] = Convert.ToInt(_sArray[i]);
}
var list = _nArray.ToList();
QuickSort(list,, _nLength - 1);
foreach (var i in list)
{
Console.WriteLine(i.ToString());
}
while (true)
{
Thread.Sleep();
}
}
//获取按枢轴值左右分流后枢轴的位置
private static int Division(List<int> list, int left, int right)
{
while (left < right)
{
int num = list[left]; //将首元素作为枢轴
if (num > list[left +])
{
list[left] = list[left +];
list[left +] = num;
left++;
}
else
{
int temp = list[right];
list[right] = list[left +];
list[left +] = temp;
right--;
}
Console.WriteLine(string.Join(",", list));
}
Console.WriteLine("--------------n");
return left; //指向的此时枢轴的位置
}
private static void QuickSort(List<int> list, int left, int right)
{
if (left < right)
{
int i = Division(list, left, right);
//对枢轴的左边部分进行排序
QuickSort(list, i +, right);
//对枢轴的右边部分进行排序
QuickSort(list, left, i -);
}
}
Ruby
class Array
def quick_sort
return self if self.length<=
k = self[]
head =
tail = self.length - 1
while head < tail
(tail-head).times do
if self[tail] < k
self[tail], self[head] = self[head], self[tail]
break
end
tail = tail -
end
(tail-head).times do
if self[head] > k
self[tail], self[head] = self[head], self[tail]
break
end
head = head +
end
end
[*(self.slice(, head).quick_sort), self[head], *(self.slice(head+1, self.length-head-1).quick_sort)]
end
end
#test
test_len =
random_array = []
test_len.times do
random_array << rand()
end
puts "random_array = [#{random_array.join(', ')}]"
puts "random_array.quick_sort = [#{random_array.quick_sort.join(', ')}]"
puts "random_array.sort = [#{random_array.sort.join(', ')}]"
puts "quick_sort #{(random_array.quick_sort == random_array.sort) ? "succeed" : 'failed'}."
Swift
func quickSort(_ list : inout [Int], low : Int , high : Int){
if low >= high{
return
}
var i = low,j = high
let temp = list[low]
while i < j{
while i < j , list[j] >= temp{
j -=
}
list[i] = list[j]
while i < j , list[i] <= temp {
i +=
}
list[j] = list[i]
}
let position = i
list[position] = temp
quickSort(&list, low: low, high: position -)
quickSort(&list, low: position +, high: high)
}
Objective-C
/**
* 快速排序
*
* @param list array
*/+(void)quickSort:(NSMutableArray *)list{
if (list.count <=) {
return;
}
[self quickSort:list startIndex: endIndex:list.count-1];
}
/**
* 快速排序
* 任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面
* 再分别对两边的数据进行快速排序
* @param list 数组
* @param start 低位索引
* @param end 高位索引
*/+(void)quickSort:(NSMutableArray *)list startIndex:(NSInteger)start endIndex:(NSInteger)end{
if (start >= end) { //低位大于高位,排序结束
return;
}
NSInteger low = start;
NSInteger high = end;
NSInteger key = [[list objectAtIndex:start] integerValue]; //取第一个数作为关键数据
while (low < high) {
//从后往前推,直到找到第一个比关键数据小的值
while ([[list objectAtIndex:high] integerValue] >= key && low < high) {
high--;
}
//将这个值与关键数据对调(关键数据处于low位置),对调完关键数据处于high位置
[list exchangeObjectAtIndex:low withObjectAtIndex:high];
//从前往后推,直到找到第一个比关键数据大的值
while ([[list objectAtIndex:low] integerValue] <= key && low < high) {
low++;
}
//将这个值与关键数据(关键数据已经处于high位置)对调,对调完关键数据处于low位置
[list exchangeObjectAtIndex:high withObjectAtIndex:low];
}
//对关键数据前面的数据进行快速排序
[self quickSort:list startIndex:start endIndex:low-];
//对关键数据后面的数据进行快速排序
[self quickSort:list startIndex:low+ endIndex:end];
}
Shell
#!/bin/bash
function array()
{
local a=(`echo "$@"`)
local s=${a[${#a[@]}-]}
local t=${a[${#a[@]}-]}
if [ "$s" -lt "$t" ];
then
i=$s
j=$t
temp=${arr[s]}
while [ "$i" -ne "$j" ]
do
while [[ "$j" -gt "$i" && "${arr[j]}" -ge "$temp" ]]
do
j=$[j-]
done
mid=${arr[j]}
arr[j]=${arr[i]}
arr[i]=$mid
while [[ "$i" -lt "$j" && "${arr[i]}" -le "$temp" ]]
do
i=$[i+]
done
mid=${arr[j]}
arr[j]=${arr[i]}
arr[i]=$mid
done
arr[i]=$temp
array arr[*] $s $[i-]
array arr[*] $[i+] $t
fi
}
arr=( 12 16 14 15 333 3 24 9 14)
array arr[*] 9
echo ${arr[*]}
作者简介:茂子,热爱编程的家伙,欢迎关注。