A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 唐永康 中级黑马   /  2012-11-11 23:24  /  3483 人查看  /  8 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

快速排序法的原理是什么?想了解一下快速排序法的原理。

点评

如果还没懂,建议你百度下,自己画画图,敲敲代码,就理解了  发表于 2012-11-12 20:36

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

8 个回复

倒序浏览
排序方法了,就是一个优化过的算法,排序算法有很多种的
http://baike.baidu.com/view/19016.htm

点评

能不能别复制的这么明显  发表于 2012-11-12 09:46
回复 使用道具 举报
我的blog里转了一篇文章 8个排序方式http://blog.csdn.net/zhuruoyun/article/details/8168739 详解了原理,推荐给你哦。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
   快速排序法是对冒泡排序的一种改进,它的基本思想是:
  通过一趟排序将拍要排序的数据分割成独立的两部分,
  其中一部分的所有数据都比另外一部分的所有数据都要
  小,然后再按此方法对这两部分数据分别进行快速排序,
  整个排序过程可以递归进行,以此达到整个数据序列变
  成有序序列。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报

快速排序顺利用递归原理,把数组无限制的分成两部分,直到所有数据都排好序为止。
分析:快速排序的基本思想是通过一趟排序将要排序的数据分割成两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后按此方法对这两部分数据分别
         进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
步骤:      
        如果要排序的数组是A[0].........A[N-1],首先任意选取一个数据(通常选用第一个数据)作为中间数据,然后将所有比他小的数都放到它前面,所有比他大的数据都放到它
后面,这个过程称为一趟快速排序。一趟快速排序的算法如下:
(1)设置两个变量i,j,排序开始的时候:i=1,j=N-1.
(2)以第一个数组元素作为中间数据,赋值给pivot,即pivot=A[0]。
(3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于X的值。
(4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于X的值,并与上一步找到的数字交换。
(5)重复3,4步,直到i>=j。
(6)然后把j所在的数字与pivot交换。
(7)最后把j以前的数组和j到最后的数组,在进行递归的快速排序。
  1. public class Sort {

  2.         /**
  3.          * 快速排序
  4.          */
  5.         public static void main(String[] args) {
  6.                 int arr[] = {4,12,5,1,97,16,3,7};

  7.                 quickSort(arr,0,arr.length-1);
  8.                 printArr(arr);

  9.         }

  10.         //用递归让整个数组序列化
  11.         private static void quickSort(int[] arr, int begin, int end) {
  12.                 if(begin>end){
  13.                         return ;
  14.                 }
  15.                 int i = onceSort(arr,begin,end);
  16.                 quickSort(arr,begin,i-1);
  17.                 quickSort(arr,i+1,end);
  18.         }

  19.         //打印数组
  20.         private static void printArr(int[] arr) {
  21.                 for(int i : arr){
  22.                         System.out.print(i+"\t");
  23.                 }
  24.                
  25.         }

  26.         //一趟快速排序,并返回用于下次分组的中间值i
  27.         public static int onceSort(int[]arr,int begin,int end){
  28.                 int i = begin;
  29.                 int j = end;
  30.                 int key = arr[i];
  31.                
  32.                 while(j>i){
  33.                         while(arr[j]>key&&j>i){
  34.                                 j--;
  35.                         }
  36.                         if(j>i){
  37.                                 arr[i] = arr[j];
  38.                                 arr[j] = key;
  39.                         }
  40.                         while(arr[i]<key&&j>i){
  41.                                 i++;
  42.                         }
  43.                         if(j>i){
  44.                                 arr[j] = arr[i];
  45.                                 arr[i] = key;
  46.                         }
  47.                 }
  48.                
  49.                 return i;
  50.         }
  51. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 刘腾 于 2012-11-12 19:34 编辑

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。

虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤。因此我的对快速排序作了进一步的说明:挖坑填数+分治法
先来看实例吧,定义下面再给出(最好能用自己的话来总结定义,这样对实现代码会有帮助)。

以一个数组作为示例,取区间第一个数为基准数。
0 12 3 4 56 78 9
72 6 57 88 60 42 83 73 48 85

初始时,i = 0;  j = 9;   X = 72
由于已经将a[0]中的数保存到X中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。
从j开始向前找一个比X小或等于X的数。当j=8,符合条件,将a[8]挖出再填到上一个坑a[0]中。a[0]=a[8]; i++;  这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于X的数,当i=3,符合条件,将a[3]挖出再填到上一个坑中a[8]=a[3]; j--;

数组变为
0 12 3 4 56 78 9
48 6 57 88 60 42 83 7388 85

i = 3;   j = 7;   X=72
再重复上面的步骤,先从后向前找,再从前向后找。
从j开始向前找,当j=5,符合条件,将a[5]挖出填到上一个坑中,a[3] = a[5]; i++;
从i开始向后找,当i=5时,由于i==j退出。
此时,i = j = 5,而a[5]刚好又是上次挖的坑,因此将X填入a[5]。

数组变为:

0 12 3 4 56 78 9
48 6 57 42 60 72 83 7388 85

可以看出a[5]前面的数字都小于它,a[5]后面的数字都大于它。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了。


对挖坑填数进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a。
2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a中。
照着这个总结很容易实现挖坑填数的代码:代码参照楼上 写的很详细



评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
快速排序:  
不需要大量辅助空间,并且是通用排序算法中最快的排序算法,是基于划分的思想。
快速排序算法本质上是通过把一个数组递归的划分为两个子数组。

递归的基本步骤:  
1. 把数组划分成以一个元素为枢纽的左右两个子数组。
2. 调用自身的左边和右边以步骤1递归。
快速排序法的核心就是递归调用划分算法,直到基值的情况,这时数组就为有序的。
快速排序的复杂度为:
O(N*logN)
   
影响效率的最大障碍:
对枢纽数据的选择是影响排序的效率。例如本例子选择枢纽数据为数组的最后一个元素,
这么选择只是为方便,然而却造成了特殊情况时效率极度下降,降到O(n2)。这种特情况就是当数据为逆序的时候。

详细内容可以参见我的博客:http://blog.sina.com.cn/s/blog_ba289cbf0101cytr.html
回复 使用道具 举报
快速排序:  
不需要大量辅助空间,并且是通用排序算法中最快的排序算法,是基于划分的思想。
快速排序算法本质上是通过把一个数组递归的划分为两个子数组。

递归的基本步骤:  
1. 把数组划分成以一个元素为枢纽的左右两个子数组。
2. 调用自身的左边和右边以步骤1递归。
快速排序法的核心就是递归调用划分算法,直到基值的情况,这时数组就为有序的。
快速排序的复杂度为:
O(N*logN)
   
影响效率的最大障碍:
对枢纽数据的选择是影响排序的效率。例如本例子选择枢纽数据为数组的最后一个元素,
这么选择只是为方便,然而却造成了特殊情况时效率极度下降,降到O(n2)。这种特情况就是当数据为逆序的时候。

详细内容可以参见我的博客:http://blog.sina.com.cn/s/blog_ba289cbf0101cytr.html
回复 使用道具 举报
徐强 发表于 2012-11-12 16:09
快速排序顺利用递归原理,把数组无限制的分成两部分,直到所有数据都排好序为止。
分析:快速排序的基本 ...

很好,很好,很好,很好,很好,很好,很好,很好,很好,很好,
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马