排序之快速排序(java)
Posted 念奕玥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序之快速排序(java)相关的知识,希望对你有一定的参考价值。
快速排序是由东尼·霍尔所发展的一种排序算法。 在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。 事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner> loop)可以在大部分的架构上很有效率地被实现出来。
基本思想
分治法。快速排序又是一种分而治之思想在排序算法上的典型应用。
使用分治法(Divide and conquer)把一个串行(list)分为两个子串行(sub-lists)。
本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快排对效率高!它是处理大数据最快的排序算法之一,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好。
基本步骤:
- 从数列中挑出一个元素,称为"基准"(pivot)。(一般是arr[0])
- 进行分区操作:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。
- 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归到最底部时,子数列的长度是零或一,也就是到了分治后到最小子数列。
递归写法如下:
public class quicksort {
public static void main(String[] args) {
int[] arr = {13,5,2,8,32,56,32,421,78,4};
sort(arr,0,arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\\t");
}
}
private static void sort(int[] arr, int left,int right){
//递归结束条件
if(left>=right){
return;
}
int low = left,high = right;
//选出基准值
int pivot = arr[low];
//以pivot为标准,小数移到pivot左边,大数右边
while (low<high){
//pivot选在了arr[low],先从后往前找
while (low<high && arr[high]>=pivot)
high--;
//遇见小数就交换
arr[low]=arr[high];
//从前往后找
while ((low<high && arr[low]<=pivot))
low++;
//遇见大数就交换
arr[high]=arr[low];
}
//pivot在low和high相交处
arr[low]=pivot;
//递归处理
sort(arr,left,low-1);
sort(arr,low+1,right);
}
}
输出结果:
2 4 5 8 13 32 32 56 78 421
非递归写法:
因为 递归的本质是栈 ,所以非递归实现的过程中,可以借助栈来保存中间变量。
中间变量就是通过Pritation函数划分区间之后左右两部分的首尾指针。
import java.util.LinkedList;
public class quicksort {
public static void main(String[] args) {
int[] arr = {13,5,2,8,32,56,32,421,78,4};
sort1(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\\t");
}
}
private static void sort1(int[] arr){
LinkedList <Integer> stack = new LinkedList<Integer>();
stack.add(0);
stack.add(arr.length-1);
while (!stack.isEmpty()){
int low = stack.removeFirst();
int high = stack.removeFirst();
int pivotIndex = partition(arr,low,high);
if(pivotIndex>low){
stack.add(low);
stack.add(pivotIndex-1);
}
if(pivotIndex<high && pivotIndex>=0){
stack.add(pivotIndex+1);
stack.add(high);
}
}
}
//分区排序
private static int partition(int[] arr,int low,int high){
if(low>=high) return -1;
int left = low ,right = high;
int pivot = arr[low];
//小数左移,大数右移
while (left<right){
while (left < right && arr[right]>=pivot)
right--;
arr[left]=arr[right];
while (left<right && arr[left]<=pivot)
left++;
arr[right]=arr[left];
}
//放置pivot
arr[left]=pivot;
//返回基准值的下标
return left;
}
输出结果:
2 4 5 8 13 32 32 56 78 421
以上是关于排序之快速排序(java)的主要内容,如果未能解决你的问题,请参考以下文章