也从排序谈起之 快速排序(2)

来源:互联网 发布:接口授权源码 编辑:程序博客网 时间:2024/04/30 04:48

上篇文章分析了基本的快速排序思想,这里也不打算再深入进去了,就这个快速排序的实现来说,就已经有了很多值得思考的东西。

我大概总结了3点:

1、关于排序中相等情况的处理

2、关于快速排序中上界、下界的选择(即lptr,rptr选哪一个)

3、由快速排序想到的快速查找,比如常用的查找集合S中的最小元,最大元问题。

 

分析如下:

1、排序中元素相等情况的处理

不健壮的算法实现对于不挑剔的测试数据来说总是很容易能得到正确的结果,但是,如果我们加大测试力度,比如增加数据数量,或者

改变测试策略,将数据相等的情况考虑进去,那么这个时候,算法就很容易出错了。

上篇文章给的程序实现是能正确处理这种情况的,不论lptr或者rptr,只要遇到和a[right]相等的元素,都会停下来,以交换lptr和rptr指向的

元素,这样看,表面上是增加了很多不必要的交换操作,实际上它使集合总体上趋于平衡。关于具体的比较,数据结构教程上都讲的比较

详细,我这也不抄袭了。就是想强调下排序过程中特殊情况的处理。

 

2、考虑到lptr,rptr的运动规律,当二者停止运动的时候,只有两种情况存在,记lptr与rptr指向了同一元素,或者lptr运动到了rptr的右边,

所以这时候显而易见,lptr既然在,其指向的元素肯定比a[right]大,故交换s[lptr]与s[right],没有任何问题。但rptr此时指向的元素肯定

小于a[right],所以不能用a[rptr]与a[right]进行交换。

 

或者当我们从最开始选择a[pivot]与a[left]交换,那么此时,情况就正好相反,应该取a[rptr]与a[left]交换。原因同上

 

3、快速排序问题

当我们要在集合S中寻找第K个最小元或最大元的时候,那么对整个集合进行排序,显然不是一个好的办法。一种好的解决方案是使用

堆排序,建立一个堆,然后依次删除K-1次根节点之后,当前的根节点元素肯定就是要求的元素。第二种好的方案就是使用快速排序,

因为我们每次选取中间节点进行分割,S被分割成S1和S2之后,S1中所有元素肯定小于S2,此时S1是从0-(lptr-1),S2是从(lptr+1)-right,

所以K如果在S1中,那么就不需要对S2再进行排序,如果在S2中,就不需要对S1进行排序,如果K==lptr,那么再好不过,它就是我们

要找的元素。

以下是快速选择的一种实现

------------------------------------------------------------------------------------------------

 10 void qselect(int a[],int left,int right,int K)
 11 {
 12     int lptr,rptr;
 13     int pviot = (left+right)/2;
 14
 15     if(left < right)
 16     {
 17         lptr = left;
 18         rptr = right -1;
 19         swap(a,pviot,right);
 20         for(;;)
 21         {
 22             for(;a[lptr] < a[right];lptr++);
 23             for(;a[rptr] > a[right];rptr--);
 24
 25             if(lptr < rptr)
 26             {
 27                 swap(a,lptr,rptr);
 28                 lptr++;
 29                 rptr--;
 30             }
 31             else
 32                 break;
 33         }
 34         swap(a,lptr,right);
 35
 36         if(K < lptr)
 37             qselect(a,left,lptr-1,K);
 38         else if(K > lptr)
 39             qselect(a,lptr+1,right,K-lptr-1);
 40     }
 41 }

      int main(void)

      { ......

 56     qselect(a,0,N-1,K-1);......}

------------------------------------------------------------------------------------------------

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一岁宝宝痰多怎么办 小孩鼻涕和痰多怎么办 鼻子老长鼻屎要怎么办 眼睛老有眼屎是怎么办 眼睛有干眼屎是怎么办 小孩流黄鼻涕是怎么办 孕妇9个月流鼻涕怎么办 流黄鼻涕两周了怎么办 大人流黄脓鼻涕怎么办 鼻子一直流鼻涕像水一样怎么办 6个月婴儿流鼻涕怎么办 9个月婴儿流鼻涕怎么办 狗狗晕车吐了怎么办 小狗又拉又吐怎么办 犬瘟热流黄鼻涕怎么办 2个月幼犬流鼻涕怎么办 5个月宝宝流鼻血怎么办 1岁宝宝感冒鼻塞怎么办 4个月宝宝鼻塞怎么办 4岁宝宝感冒鼻塞怎么办 宝宝4个月流鼻涕怎么办 3个月的宝宝鼻塞怎么办 50天的小孩鼻塞怎么办 鼻子流脓鼻涕2周怎么办 两岁宝宝流清鼻涕怎么办 1岁宝宝流黄鼻涕怎么办 宝宝上火流黄鼻涕怎么办 一周岁宝宝流清鼻涕怎么办 一周岁流清鼻涕怎么办 4岁宝宝感冒发烧怎么办 6个月宝宝流鼻涕怎么办 8岁儿童感冒发烧怎么办 婴儿感冒咳嗽怎么办%3f 小孩流鼻涕鼻塞怎么办最简单方法 宝宝鼻炎鼻子不通气怎么办 小孩晚上睡觉鼻子不通气怎么办 孩子晚上睡觉鼻子不通气怎么办 3个月婴儿流鼻涕怎么办 一个月宝宝鼻塞流鼻涕怎么办 我的鼻子不通气怎么办 鼻子擦多了疼怎么办