您的位置:首页 > 编程语言 > Java开发

高级排序之快速排序 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虚拟机,讲得很详细.而且递归层数太多需考虑函数调用消耗资源

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;
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息