高级排序之快速排序 O(n*logn)
2011-04-06 10:39
267 查看
毫无疑问,快速排序是最流行的排序算法,因为有充足的理由,在大多数情况下,快速排序都是最快的,执行时间为O(N*logN)级。(这只是对内部排序或则说随即存储器内的排序而言,对于在磁盘文件的数据进行排序,其他的排序算法可能更好。)快速排序是在1962年由C.A.R.Hoare 发现的。
为了理解快速排序算法,应该对划分分治的概念非常熟悉。快速排序算法本质上通过把一个数组划分为两个子数组,然后递归地调用自身为每个子数组进行快速排序来实现的。但是,对这个基本的设计还需要进行一些架构。算法还必须选择枢纽以及对小的划分区域进行排序。看过这个主要算法简化代码以后,还要对其进行求精。
正如大家看到图解一样,基本上是3个基本步骤
1.把数组或则子数组划分成左边(较小的关键字)的一组和右边(较大的关键字)的一组
2.调用自身对左边的一组进行排序
3.再次调用自身右边的一组进行排序
JAVA代码实现如下,尚未清楚算法思路的,看递归快速排序,条理清晰易懂.实际应用中使用非递归算法,递归可能因递归层数太多导致JVM虚拟机堆栈内存不足而抛出StackOverflowError,具体原因请看深入JAVA虚拟机,讲得很详细.而且递归层数太多需考虑函数调用消耗资源
为了理解快速排序算法,应该对划分分治的概念非常熟悉。快速排序算法本质上通过把一个数组划分为两个子数组,然后递归地调用自身为每个子数组进行快速排序来实现的。但是,对这个基本的设计还需要进行一些架构。算法还必须选择枢纽以及对小的划分区域进行排序。看过这个主要算法简化代码以后,还要对其进行求精。
正如大家看到图解一样,基本上是3个基本步骤
1.把数组或则子数组划分成左边(较小的关键字)的一组和右边(较大的关键字)的一组
2.调用自身对左边的一组进行排序
3.再次调用自身右边的一组进行排序
JAVA代码实现如下,尚未清楚算法思路的,看递归快速排序,条理清晰易懂.实际应用中使用非递归算法,递归可能因递归层数太多导致JVM虚拟机堆栈内存不足而抛出StackOverflowError,具体原因请看深入JAVA虚拟机,讲得很详细.而且递归层数太多需考虑函数调用消耗资源
package com.fjl.util.sort; import java.util.Stack; /** * @author 房佳龙 * @date:2011-4-5 * 快速排序 */ public class QuickSort<T extends Comparable<T>> extends AbstractSort implements Sort<T> { /** * 泛型对象快速排序 */ @Override public T[] sort(T[] arr) { Stack<PartitionNode> stack = new Stack<PartitionNode>(); stack.push(new PartitionNode(0,arr.length-1)); PartitionNode node; int left, right; while(stack.size()>0){ node=stack.pop(); left=node.getLeft(); right=node.getRight(); if(left>=right) continue; int lp = left; int rp = right; while(lp<rp){ while(lp<rp&&arr[lp].compareTo(arr[rp])<=0){ lp++; } swap(arr,lp,rp); while(rp>lp&&arr[rp].compareTo(arr[lp])>=0){ rp--; } swap(arr,lp,rp); stack.push(new PartitionNode(left,lp-1)); stack.push(new PartitionNode(rp+1,right)); } } return arr; } @Override public int[] sort(int[] arr) { return partitionWithOutRecurving(arr); } /** * 递归式快速排序 * @param arr * @param left * @param right * @return */ private int[] partitionWithRecurving(int[] arr,int left,int right){ if(left>=right){ return arr; } int lp = left; int rp = right; while(lp<rp){ while(lp<rp&&arr[lp]<=arr[rp]){ lp++; } swap(arr,lp,rp); while(rp>lp&&arr[rp]>=arr[lp]){ rp--; } swap(arr,lp,rp); } partitionWithRecurving(arr,left,lp-1); partitionWithRecurving(arr,rp+1,right); return arr; } /** * 非递归式排序 * @param arr * @param left * @param right * @return */ private int[] partitionWithOutRecurving(int[] arr){ Stack<PartitionNode> stack = new Stack<PartitionNode>(); stack.push(new PartitionNode(0,arr.length-1)); PartitionNode node; int left, right; while(stack.size()>0){ node=stack.pop(); left=node.getLeft(); right=node.getRight(); if(left>=right) continue; int lp = left; int rp = right; while(lp<rp){ while(lp<rp&&arr[lp]<=arr[rp]){ lp++; } swap(arr,lp,rp); while(rp>lp&&arr[rp]>=arr[lp]){ rp--; } swap(arr,lp,rp); stack.push(new PartitionNode(left,lp-1)); stack.push(new PartitionNode(rp+1,right)); } } return arr; } private class PartitionNode{ private int left; private int right; private PartitionNode(int left,int right){ this.left=left; this.right=right; } public int getLeft() { return left; } public int getRight() { return right; } } }
相关文章推荐
- 高级排序-快速排序-利用三数据取中划分的快速排序算法
- 快速排序, 堆排序,归并排序【N*logN】
- 高级排序-快速排序-使用插入排序来处理小于10个数据项的子数组,使快速排序性能发挥到极致。
- 算法——高级排序——快速排序,归并排序,希尔排序
- (十六)高级排序—快速排序
- 高级排序算法--快速排序
- 高级排序:希尔排序 O(N*(logN)^2)
- 高级排序算法--快速排序
- javascript高级排序算法-希尔排序、归并排序、快速排序
- java数据结构与算法-高级排序-快速排序
- 排序高级之交换排序_快速排序
- 数据结构与算法之高级排序(快速/归并)<十二>
- 高级排序-快速排序,最右边的值为枢纽
- 时间复杂度为O(N*logN)的排序算法——归并排序、快速排序、堆排序
- Java高级排序(希尔排序,快速排序,堆排序,归并排序,桶排序)
- 数据结构与算法之--高级排序:shell排序和快速排序
- 第十六周--快速排序
- 快速排序基本思路(通俗易懂+例子)
- 快速排序
- 高级排序