黑马程序员:快速排序及随机化算法
2013-12-06 22:24
239 查看
-------
android培训、java培训、期待与您交流! ----------
快速排序(Quicksort)是对冒泡排序的一种改进。由C.
A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序的基本思想:首先将待排序记录序列中的所有记录作为当前待排序区域,从中任选取一个记录(通常可选取第一个记录),以它为关键字作为枢轴,凡是其关键字小于枢轴的记录均移动到该关键字之前,反之移动到该记录之后,这一趟排序后,记录的无序序列R[s..t]将分割成两部分,R[s..i-1]和R[i+1..t],且R[j].key<=R[i].key(s<=j<=i-1,R[i].key为枢轴,i+1<=k<=t)。
快速排序的实例:
一趟排序的过程
初始关键字序列: [51] 33 62 96 87 17 28 51
R[0]=[51] i↑(枢轴) ↑j
J向前扫描 i↑ ↑j
第一次交换之后: 28 33 62 96 87 17 [51] 51
i↑ ↑j
I向后扫描 i↑ ↑j
第二次交换之后: 28 33 [51] 96 87 17 62 51
i↑ ↑j
J向前扫描 i↑ ↑j
第三次交换之后: 28 33 17 96 87 [51] 62 51
I向后扫描 i↑ ↑j
第四次交换之后: 28 33 17 [51] 87 96 62 51
J向前扫描 i↑ ↑j
完成一趟排序: 28 33 17 [51] 87 96 62 51
快速排序全过程
初始关键字序列: [51] 33 62 96 87 17 28 51
一趟排序之后: [28 33 17] 51 [87 96 62 51]
分别进行快速排序: [17] 28 [33] 51 [51 62] 87 [96]
51 [62]
有序序列: 17 28 33 51 51 62 87 96
快速排序的Java算法:
public
class Test2 {
/**
* @param args
* 快速排序
*
*/
public
static void main(String[] args) {
// TODO Auto-generatedmethod stub
//定义一维数组
int[] R = {132,24,4,436,547,65,87,8,6,9,780,7,325,57,54,46,35,3,42,4};
//掉用quickSort方法,对一维数组排序,初始化low为0,最大值
quickSort(R, 0, R.length - 1);
//用for循环输出排序好的数组
for(int i = 0; i < R.length; i++) {
System.out.print(R[i] +
" ");
}
}
//快速排序
//定义quickSort方法
static
void quickSort(int R[],
int low, int height) {
//对记录R[low...height]进行快速排序
if(low < height) {
int result =
partition(R, low,height);
quickSort(R, low, result -1);
quickSort(R, result + 1,height);
}
}
//定义partition方法
static
int partition(int R[],
int low, int height) {
//交换记录子序列 R[low...height]的记录,使轴记录交换到正确的位置,并返回其所在的位置
int key = R[low];
//使用key存放枢轴记录的关键字
while(low < height) {
//从表的两端交替向中间扫描
while(low < height && R[height] >=key) {
height--;
}
R[low] = R[height]; //将比轴小的记录移到低端
while(low < height && R[low] <= key){
low++;
}
R[height] = R[low]; //将比轴大的记录移到高端
}
R[low] = key; //轴记录到位
return low;
//返回轴记录位置
}
}
快速排序所需的平均时间复杂度为O(n log n)。就平均时间而言,快速排序是目前被认为最好的内部排序方法。但是,若待排记录的初始状态为关键字有序,快速排序将锐化成起泡排序,其时间复杂度为O(n2)。也就是说,一次划分后枢轴两侧的记录数量越接近,排序速度越快,待排序记录越有序,排序速度越慢。为避免排序后记录集中在枢轴一侧的情况,需要在进行快速排序之前,进行”预处理”。这里要说的是随机化快速排序。
随机化快速排序:在待排序序列中随机确定一个记录作为轴值,并把它与第一个记录交换,则一次划分后得到期望均衡的两个子序列,,从而使算法的行为不受待排序序列的不同输入实例的影响,使快速排序在最坏的情况下的时间性能趋近于 平均情况的时间性能。
随机化快速排序代码:
import java.util.Random;
public
class RandomQuickSort {
/**
* @param args
* 随机化快速排序
*
*/
private
static Random rnd=new Random();
public
static void main(String[] args) {
// TODO Auto-generatedmethod stub
//定义一维数组
int[] R ={132,24,4,436,547,65,87,8,6,9,780,7,325,57,54,46,35,3,42,4};
//掉用quickSort方法,对一维数组排序,初始化low为0,最大值
quickSort(R, 0, R.length - 1);
//用for循环输出排序好的数组
for(int i = 0; i < R.length; i++) {
System.out.print(R[i] +
" ");
}
}
//快速排序
//定义quickSort方法
static
void quickSort(int R[],
int low, int height) {
//对记录R[low...height]进行快速排序
if(low < height) {
int result =
partition(R, low,height);
quickSort(R, low, result -1);
quickSort(R, result + 1,height);
}
}
//定义partition方法
static
int partition(int R[],
int low, int height) {
int point =
rnd.nextInt(height-low)+low;
int temp = R[low];
R[low]= R[point];
R[point]= temp;
//交换记录子序列 R[low...height]的记录,使轴记录交换到正确的位置,并返回其所在的位置
int key = R[low];
//使用key存放枢轴记录的关键字
while(low < height) {
//从表的两端交替向中间扫描
while(low < height && R[height] >=key) {
height--;
}
R[low] = R[height]; //将比轴小的记录移到低端
while(low < height && R[low] <= key){
low++;
}
R[height] = R[low]; //将比轴大的记录移到高端
}
R[low] = key; //轴记录到位
return low;
//返回轴记录位置
}
}
android培训、java培训、期待与您交流! ----------
快速排序(Quicksort)是对冒泡排序的一种改进。由C.
A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序的基本思想:首先将待排序记录序列中的所有记录作为当前待排序区域,从中任选取一个记录(通常可选取第一个记录),以它为关键字作为枢轴,凡是其关键字小于枢轴的记录均移动到该关键字之前,反之移动到该记录之后,这一趟排序后,记录的无序序列R[s..t]将分割成两部分,R[s..i-1]和R[i+1..t],且R[j].key<=R[i].key(s<=j<=i-1,R[i].key为枢轴,i+1<=k<=t)。
快速排序的实例:
一趟排序的过程
初始关键字序列: [51] 33 62 96 87 17 28 51
R[0]=[51] i↑(枢轴) ↑j
J向前扫描 i↑ ↑j
第一次交换之后: 28 33 62 96 87 17 [51] 51
i↑ ↑j
I向后扫描 i↑ ↑j
第二次交换之后: 28 33 [51] 96 87 17 62 51
i↑ ↑j
J向前扫描 i↑ ↑j
第三次交换之后: 28 33 17 96 87 [51] 62 51
I向后扫描 i↑ ↑j
第四次交换之后: 28 33 17 [51] 87 96 62 51
J向前扫描 i↑ ↑j
完成一趟排序: 28 33 17 [51] 87 96 62 51
快速排序全过程
初始关键字序列: [51] 33 62 96 87 17 28 51
一趟排序之后: [28 33 17] 51 [87 96 62 51]
分别进行快速排序: [17] 28 [33] 51 [51 62] 87 [96]
51 [62]
有序序列: 17 28 33 51 51 62 87 96
快速排序的Java算法:
public
class Test2 {
/**
* @param args
* 快速排序
*
*/
public
static void main(String[] args) {
// TODO Auto-generatedmethod stub
//定义一维数组
int[] R = {132,24,4,436,547,65,87,8,6,9,780,7,325,57,54,46,35,3,42,4};
//掉用quickSort方法,对一维数组排序,初始化low为0,最大值
quickSort(R, 0, R.length - 1);
//用for循环输出排序好的数组
for(int i = 0; i < R.length; i++) {
System.out.print(R[i] +
" ");
}
}
//快速排序
//定义quickSort方法
static
void quickSort(int R[],
int low, int height) {
//对记录R[low...height]进行快速排序
if(low < height) {
int result =
partition(R, low,height);
quickSort(R, low, result -1);
quickSort(R, result + 1,height);
}
}
//定义partition方法
static
int partition(int R[],
int low, int height) {
//交换记录子序列 R[low...height]的记录,使轴记录交换到正确的位置,并返回其所在的位置
int key = R[low];
//使用key存放枢轴记录的关键字
while(low < height) {
//从表的两端交替向中间扫描
while(low < height && R[height] >=key) {
height--;
}
R[low] = R[height]; //将比轴小的记录移到低端
while(low < height && R[low] <= key){
low++;
}
R[height] = R[low]; //将比轴大的记录移到高端
}
R[low] = key; //轴记录到位
return low;
//返回轴记录位置
}
}
快速排序所需的平均时间复杂度为O(n log n)。就平均时间而言,快速排序是目前被认为最好的内部排序方法。但是,若待排记录的初始状态为关键字有序,快速排序将锐化成起泡排序,其时间复杂度为O(n2)。也就是说,一次划分后枢轴两侧的记录数量越接近,排序速度越快,待排序记录越有序,排序速度越慢。为避免排序后记录集中在枢轴一侧的情况,需要在进行快速排序之前,进行”预处理”。这里要说的是随机化快速排序。
随机化快速排序:在待排序序列中随机确定一个记录作为轴值,并把它与第一个记录交换,则一次划分后得到期望均衡的两个子序列,,从而使算法的行为不受待排序序列的不同输入实例的影响,使快速排序在最坏的情况下的时间性能趋近于 平均情况的时间性能。
随机化快速排序代码:
import java.util.Random;
public
class RandomQuickSort {
/**
* @param args
* 随机化快速排序
*
*/
private
static Random rnd=new Random();
public
static void main(String[] args) {
// TODO Auto-generatedmethod stub
//定义一维数组
int[] R ={132,24,4,436,547,65,87,8,6,9,780,7,325,57,54,46,35,3,42,4};
//掉用quickSort方法,对一维数组排序,初始化low为0,最大值
quickSort(R, 0, R.length - 1);
//用for循环输出排序好的数组
for(int i = 0; i < R.length; i++) {
System.out.print(R[i] +
" ");
}
}
//快速排序
//定义quickSort方法
static
void quickSort(int R[],
int low, int height) {
//对记录R[low...height]进行快速排序
if(low < height) {
int result =
partition(R, low,height);
quickSort(R, low, result -1);
quickSort(R, result + 1,height);
}
}
//定义partition方法
static
int partition(int R[],
int low, int height) {
int point =
rnd.nextInt(height-low)+low;
int temp = R[low];
R[low]= R[point];
R[point]= temp;
//交换记录子序列 R[low...height]的记录,使轴记录交换到正确的位置,并返回其所在的位置
int key = R[low];
//使用key存放枢轴记录的关键字
while(low < height) {
//从表的两端交替向中间扫描
while(low < height && R[height] >=key) {
height--;
}
R[low] = R[height]; //将比轴小的记录移到低端
while(low < height && R[low] <= key){
low++;
}
R[height] = R[low]; //将比轴大的记录移到高端
}
R[low] = key; //轴记录到位
return low;
//返回轴记录位置
}
}
相关文章推荐
- 黑马程序员之数据结构学习笔记:快速排序
- 黑马程序员————java实现快速排序
- 黑马程序员---C 语言中快速排序数组,不额外占用内存空间
- 黑马程序员_C语言基础_数组之冒泡排序、快速选择排序、折半查找
- 黑马程序员技术博客之快速排序
- 黑马程序员--浅谈快速排序
- 快速排序的随机化算法
- 利用随机化快速排序求带权中位数C++实现
- 快速排序的深入分析
- 快速排序 归并排序 堆排序 希尔排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 快速排序
- 快速排序源代码
- 算法小记:快速排序
- 排序算法之快速排序 JAVA快速排序算法
- 排序--快速排序
- java实现快速排序和随机快速排序
- 冒泡排序,快速排序,堆排序比较
- 快速排序(C语言)
- 小学生图解排序算法:⑤快速排序