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

java快速排序

2013-01-01 15:42 190 查看
[size=medium]先简单说一下快速排序的原理(思路):
1、给定一个数组,选取其中一个元素作为枢纽元(pivot)通常为数组最中间的那个元素;
2、由枢纽元(pivot)将数组分为不相交的2个集合,S1和S2;
3、从S1的第一个元素开始和枢纽元(pivot)比较,找到第一个大于枢纽元(pivot)的元素后停止;
4、从S2的最后一个元素开始和枢纽元(pivot)比较,找到第一个小于枢纽元(pivot)的元素后停止;
5、交换第3步和第4步找到的2个元素,递归此操作;
6、此时枢纽元(pivot)左边集合S1都比枢纽元(pivot)小,右边集合S2都比枢纽元(pivot)大,递归2、3、4、5步,直到所有元素有序。

例如:
第1步:13、81、92、43、[color=red]65[/color]、31、57、26、75 选取枢纽元(pivot)65
第2步:S1(13、81、92、43)找到第一个大于65的数[color=blue]81[/color],S2(31、57、26、75)找到第一个小于65的数([color=red]从后往前找[/color])[color=blue]26[/color]
第3步:交换81和26的位置S1(13、26、92、43)S2(31、57、81、75)
第4步:递归操作,最后结果:S1(13、26、57、43、31)S2(92、81、75),此时数组元素顺序为:13、26、57、43、31、[color=red]65[/color]、92、81、75
第5步:分别递归操作S1和S2,最后结果:13、26、31、43、57、65、75、81、92[color=blue](有序数组)[/color]

代码如下:[/size]
/**
* 快速排序
*
* @param nums
*/
public static void quickSort(int[] nums)
{
if (null == nums || nums.length < 1)
return;

final int len = nums.length;
sort(nums, 0, len-1);
}

private static void sort(int[] nums, int low, int high)
{
if (low < high)
{
int m = getPartition(nums, low, high);
sort(nums, low, m-1);
sort(nums, m+1, high);
}
}

private static int getPartition(int[] nums, int low, int high)
{
int tmp = nums[(low+high)/2];
while (low < high)
{
while(low < high && nums[high] > tmp)
{
high--;
}
while (low < high && nums[low] < tmp)
{
low++;
}
if (low < high)
{
swap(nums, low, high);
}
}
return low;
}

/**
* 交换元素
*
* @param nums
* @param i
* @param j
*/
private static void swap(int[] nums, int i, int j)
{
if (i == j)
return;

int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}


[size=large]运行测试,测试结果ok,是不是就没问题了呢?采用随机数组测试,发现只要数组中有相同元素存在,就会导致没有结果(死循环)!!why?

稍微修改一下[color=red]getPartition[/color]方法即可:在交换2个元素之前判断一下是否相等[/size]
private static int getPartition(int[] nums, int low, int high)
{
int tmp = nums[(low+high)/2];
while (low < high)
{
while(low < high && nums[high] > tmp)
{
high--;
}
while (low < high && nums[low] < tmp)
{
low++;
}
if (low < high)
{
if (nums[low] == nums[high])
{
low++;
continue;
}
swap(nums, low, high);
}
}
return low;
}


[size=large][color=blue]
ok,再接着测试,没问题了。。。。

备注:可以单独写一个检查数组是否有序的方法[/color][/size]
/**
* 检查数组是否有序
*
* @param nums
* @return true:有序 false:无序
*/
private static boolean checkIsSortNums(int[] nums)
{
boolean flag = true;
int tmp = -1;
final int len = nums.length;
for (int i = 0; i < len; i++)
{
if (i > 0 && nums[i] < tmp)
{
flag = false;
System.err.println("该数组不是有序数组!!!");
break;
} else
{
tmp = nums[i];
}
}
return flag;
}
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: