您的位置:首页 > 产品设计 > UI/UE

【算法导论-010】快速排序(quickSort)

2014-08-10 15:42 274 查看
1、算法思想

《算法导论》170页第7章QuickSort,不再赘述。

2、java实现

参考:《算法导论》171页伪码,注意,这里的partition(int[]
array, int start, int end)函数不是原始版本

public class QuickSortTest {

/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] array = { 2, 2, -20, 2, 100, -1, 1, 0, 3 };
quickSort(array, 0, array.length - 1);

for (int i : array) {
System.out.println(i);
}

}

public static void quickSort(int[] array, int start, int end) {
if (start < end) {
int middle = partition(array, start, end);
quickSort(array, start, middle - 1);
quickSort(array, middle + 1, end);
}
}

/*
* 以最后一个元素值为pivot元素,从前往后移动i和j两个指针,i后j前,如果当前元素大于pivot元素,i不动,j递增1;如果当前元素小于pivot元素
* ,i增1,交换array[i](大于pivot元素)和array[j](小于pivot元素); 移动完毕后将array[i +
* 1]与array[end]交换,即保证了i+1左侧元素都小于array[i + 1],右侧都大于array[i + 1]
*/
public static int partition(int[] array, int start, int end) {
int privotElement = array[end];
int i = start - 1;
for (int j = start; j <= end - 1; j++) {
if (array[j] <= privotElement) {
i++;
/*如果i、j指向同一个元素或者指向不同元素但是元素值相同,不用交换(在算法导论171页中的伪码中多一层判断)*/

if (i != j && array[i] != array[j]) {
array[i] ^= array[j];
array[j] ^= array[i];
array[i] ^= array[j];
}
}

}
/*交换基准元素与array[i + 1]*/
if (array[i + 1] != array[end]) {
array[i + 1] ^= array[end];
array[end] ^= array[i + 1];
array[i + 1] ^= array[end];
}
return i + 1;
}

}
3、快速排序的随机化版本

参考:《算法导论》179页伪码

/*随机选取pivot元素*/
public static int randomizedPartition(int[] array, int start, int end) {
int randomNumber=new Random().nextInt(end-start)+start;
if (array[randomNumber]!=array[end]) {
array[randomNumber]^=array[end];
array[end]^=array[randomNumber];
array[randomNumber]^=array[end];
}
return partition(array, start, end);
}
***********************************************************************************************************

仅仅修改:
public static void quickSort(int[] array, int start, int end) {
if (start < end) {
//          int middle = partition(array, start, end);
<span style="color:#009900;"><strong> int middle=randomizedPartition(array, start, end);</strong></span>
quickSort(array, start, middle - 1);
quickSort(array, middle + 1, end);
}
}
4、partition(int[]
array, int start, int end)原始版本

思路:《算法导论》185页
/*原始的partition过程*/
public static int  originalPartition(int[] array, int start, int end) {
int privotElement = array[start];
while (start<end) {
/*end--之后可能导致start>end*/
while (start<end&&array[end]>=privotElement) {
end--;
}
array[start]=array[end];
/*end--之后可能导致start>end,start++之后也可能导致start>end*/
while (start<end&&array[start]<=privotElement) {
start++;
}
array[end]=array[start];

}
array[start]=privotElement;
return start;
}


5、非递归版本的快速排序
参考:http://www.cnblogs.com/zhangchaoyang/articles/2234815.html

/*非递归版本,使用一个stack来记录待排序的边界*/
public static void quickSort2
(int[] array, int start, int end)
{
Stack<Integer> stack =new Stack<Integer>();
if (start<end)
{
int middle=originalPartition(array, start, end);
if (start<middle-1)
{
stack.push(start);
stack.push(middle-1);
}
if (middle+1<end)
{
stack.push(middle+1);
stack.push(end);
}
while (!stack.empty())
{
int currentEnd=stack.pop();
int currentStart=stack.pop();
middle=originalPartition(array, currentStart, currentEnd);
if (currentStart<middle-1)
{
stack.push(currentStart);
stack.push(middle-1);
}
if (middle+1<currentEnd)
{
stack.push(middle+1);
stack.push(currentEnd);
}
}

}

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