排序与查找实例(三):快速排序
来源:互联网 发布:u盘安装linux系统教程 编辑:程序博客网 时间:2024/05/19 15:19
快速排序算法和归并排序类似,都是属于分治算法。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
步骤为:
从数列中挑出一个元素,称为 “基准”(pivot),重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
虽然快速排序是分治算法,但其中主要的操作是分区操作,这个操作的复杂性应该是线性的。划分的实现由很多种,朴素的实现是选取第一个元素和最后一个元素作为基准作为划分。算法导论一书给出的partition 函数是取最后一个元素作为基准,然后通过一遍循环交换元素。代码虽然简洁,但是初看起来不太易懂,建议在纸上模拟下过程。此种方法相对来说交换元素的次数也比较多,后面会给出一种优化的操作。
具体实现如下:
/**
*@Title: QuickSort.java
*@Package sortandsearch
*@Description: TODO
*@author peidong
*@date 2017-5-10 上午9:34:54
*@version V1.0
*/
packagesortandsearch;
/**
* @ClassName: QuickSort
* @Description: 快速排序实例
* @date 2017-5-10 上午9:34:54
*
*/
publicclass QuickSort {
static int num = 0; //快排的比较次数
/**
*
* @Title: partition
* @Description: 快排的核心,划分比较
* @param arr
* @param low
* @param high
* @return
* @return int
* @throws
*/
public static int partition(int[] arr,int low, int high){
//临时变量,用于保存初始值
int key = arr[low];
//开始比较
while(low < high){
while(low < high&& arr[high] >= key){ //从后向前查找直到小的
high--;
num++;
}
//找到之后进行交换
arr[low] = arr[high]; //(此时因low=high或data[high]<key)将high下标处的数赋给low下标处的数,保证data[low]<key
while(low < high&& arr[low] <= key){ //从前向后找,直到找到大的
low++;
num++;
}
//找到之后交换
arr[high] = arr[low]; //(此时因low=high或data[low]>key)将low下标处的数赋给high下标处的数,保证data[high]>key
}
//查找完成之后进行赋值
arr[low] = key;
return low;
}
/**
*
* @Title: quickSort
* @Description: 快排,递归
* @param arr
* @param low
* @param high
* @return
* @return int[]
* @throws
*/
public static int[] quickSort(int[] arr,int low, int high){
if(low < high){
int res = partition(arr,low, high);
//递归排序
quickSort(arr, low, res);//对low到result下标间数进行排序
quickSort(arr, res + 1,high); //对result+1到high下标间数进行排序
}
return arr;
}
/**
*@Title: main
*@Description: 测试用例
*@param args
*@return void
*@throws
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {8, 5, 7, 1, 99, 44,78, 22};
System.out.println("原始数组:");
for(int a : arr){
System.out.print(a + "");
}
int[] res = quickSort(arr, 0,arr.length - 1);
System.out.println();
System.out.println("快排后数组");
for(int a : res){
System.out.print(a + "");
}
System.out.println();
System.out.println("比较次数:" + num);
}
}
快排的时间复杂度,最好的情况下是O(nlgn),最坏的情况下位O(n^2)。当待排序数据基本无序时,快排的速度是最快的,而当数据是基本有序时,其反而是最慢的。
- 排序与查找实例(三):快速排序
- 快速排序与查找
- 排序与查找实例(七):基数排序
- 快速排序与 二分查找
- 排序与查找实例(二):冒泡排序
- 排序与查找实例(四):归并排序
- 排序与查找实例(五):堆排序
- 排序与查找实例(六):计数排序
- 快速排序(三)
- 排序(冒泡排序与快速排序)
- 简单的快速排序与二分查找
- 二分查找算法与快速排序
- 【排序三】交换排序(冒泡排序&&快速排序)
- 排序(三)堆排序、归并排序、快速排序
- C实例---快速排序(冒泡排序)
- C语言排序与查找实例
- 【十七】排序算法(三)--快速排序
- 排序算法(三) 快速排序
- RxSwift基本使用(一)
- Delphi打开网址链接的几种方法
- 集群session共享方案(有shiro共享session的方案)
- 调用ffmpeg库生成AAC静音帧packet
- 字符逆序
- 排序与查找实例(三):快速排序
- Unsupported major.minor version 52.0
- 前_Fri Jun 16 00:00:00 CST 2017_转换后2017/6/13 15:36:39_IllegalArgumentException
- lock-free&wait-free
- 模拟和仿真的区别
- 结合个人经历总结的前端入门方法(这才是真的入门经典)
- Spring-Cloud系列第5篇:spring-cloud-config-eureka-ribbon
- Git的理解学习笔记。
- JS之function2(对象属性方法作用域)