算法导论学习笔记(1)——快排中hoarePartition的实现(问题已解决)
2012-12-08 01:34
831 查看
打算在学期结束之前(1月19日)看完,目前94页,总共六百页,不完全做习题及思考题(不细致考虑各种时间)。
之所以发表这个是公开一下,算是对自己的监督吧。以下进入正题
实现各种算法时都OK,在快速排序这里第一次遇到问题,算法出错,hoarePartition是快速排序中用到的一个比较古老的分块算法。
伪代码
HOARE-PARTITION(A,p,r)
{
x=A[p]
i=p-1
j=r+1
while(1)
{
do repeat j--
until A[j]<=x
repeat i++
until A[i]>=x
if i<j
then exchange A[i] and A[j]
else return j
}
}
思维比较清晰的算法,当同时找到坐标x两端的异常值时,左右互换
C代码
其实问题并不出在Partition这个函数里,而是在Dosort函数里。上面这个Dosort函数简单地修改了之前另一个Partition搭配的Dosort,两者思想有细微区别。
先来看之前的Partition。
再来看HoarePartition
两者的区别是:前面那种在Partition过程中就将坐标轴元素放在排序好的位置上,自然在DOsort的迭代过程中不用再考虑该元素,但Hoare则没有这样做,在Hoare匹配的Dosort迭代时自然要将该元素也纳入迭代的考虑范围。
来看两个Dosort
之前那一种
Hoare对应的Dosort
以上。
之所以发表这个是公开一下,算是对自己的监督吧。以下进入正题
实现各种算法时都OK,在快速排序这里第一次遇到问题,算法出错,hoarePartition是快速排序中用到的一个比较古老的分块算法。
伪代码
HOARE-PARTITION(A,p,r)
{
x=A[p]
i=p-1
j=r+1
while(1)
{
do repeat j--
until A[j]<=x
repeat i++
until A[i]>=x
if i<j
then exchange A[i] and A[j]
else return j
}
}
思维比较清晰的算法,当同时找到坐标x两端的异常值时,左右互换
C代码
1 #include <stdio.h> 2 3 void RandomDoSort(int A[],int begin,int end); 4 int Hoare_Partition(int A[],int begin,int end); 5 6 void ChangeTwoInt(int* a,int* b); 7 8 void main() 9 { 10 int A[12]={13,19,9,5,12,8,7,4,21,2,6,11}; 11 RandomDoSort(A,0,11); 12 for (int i=0;i<12;i++) 13 { 14 printf("%d\n",A[i]); 15 } 16 } 17 18 19 void RandomDoSort(int A[],int begin,int end) 20 { 21 int q=0; 22 if(begin<end) 23 { 24 q=Hoare_Partition(A,begin,end); 25 DoSort(A,begin,q-1); 26 DoSort(A,q+1,end); 27 } 28 } 29 30 int Hoare_Partition(int A[],int begin,int end) 31 { 32 int xtemp=A[begin]; 33 int i=begin-1; 34 int j=end+1; 35 while (1) 36 { 37 j--; 38 if (A[j]<=xtemp) 39 { 40 while(A[i]<xtemp) 41 { 42 i++; 43 } 44 } 45 if (i<j) 46 { 47 ChangeTwoInt(&A[i],&A[j]); 48 } 49 else 50 { 51 return j; 52 } 53 } 54 } 55 56 void ChangeTwoInt(int* a,int* b) 57 { 58 int temp=*a; 59 *a=*b; 60 *b=temp; 61 } 最后结果出错,有一个数没排序上,睡觉去,明早起来调试解决这问题
其实问题并不出在Partition这个函数里,而是在Dosort函数里。上面这个Dosort函数简单地修改了之前另一个Partition搭配的Dosort,两者思想有细微区别。
先来看之前的Partition。
int Partition(int A[],int begin,int end) { int x=A[end]; int i=begin-1; int temp=0; for(int j=begin;j<=end-1;j++) { if(A[j]<x) { i++; temp=A[j]; A[j]=A[i]; A[i]=temp; } } temp=A[i+1]; //将坐标轴元素放在排序好的位置上 A[i+1]=A[end]; A[end]=temp; return i+1; }
再来看HoarePartition
int Hoare_Partition(int A[],int begin,int end) { int xtemp=A[begin]; int i=begin-1; int j=end+1; while (1) { j--; if (A[j]<=xtemp) { while(A[i]<xtemp) { i++; } } if (i<j) { ChangeTwoInt(&A[i],&A[j]); } else { return j; } } }
两者的区别是:前面那种在Partition过程中就将坐标轴元素放在排序好的位置上,自然在DOsort的迭代过程中不用再考虑该元素,但Hoare则没有这样做,在Hoare匹配的Dosort迭代时自然要将该元素也纳入迭代的考虑范围。
来看两个Dosort
之前那一种
void DoSort(int A[],int begin,int end) { int q=0; if(begin<end) { q=Partition(A,begin,end); DoSort(A,begin,q-1); //A[q]不需要再处理 DoSort(A,q+1,end); } }
Hoare对应的Dosort
void HoareDoSort(int A[],int begin,int end) { int q=0; if(begin<end) { q=Hoare_Partition(A,begin,end); DoSort(A,begin,q); //需要对A[q]再处理 DoSort(A,q+1,end); } }
以上。
相关文章推荐
- 精确覆盖问题学习笔记(五)——优化算法的实现代码
- 精确覆盖问题学习笔记(三)——算法的初步实现
- 韩顺平_PHP程序员玩转算法公开课(第一季)05_使用单链表解决约瑟夫问题_学习笔记_源代码图解_PPT文档整理
- 算法导论学习笔记(十三):动态规划(三):01背包问题
- Java 学习笔记--解决一个类实现多个接口的问题
- 【算法导论学习笔记】最大子数组问题
- 程序员编程艺术学习笔记(三续)Top K算法问题的实现
- 【JAVAWEB学习笔记】24_filter实现自动登录和解决全局的编码问题
- JDCB学习笔记 -- day05 实现一个用户的登录功能及解决SQL注入问题
- 算法导论学习笔记—Strassen算法的Java实现
- 算法学习笔记----用动态规划解决钢管切割问题
- 【算法导论学习-31】分治法解决同一个数连乘问题
- Java学习笔记--解决一个类实现多个接口的问题
- 算法学习笔记之四:巧妙运用指针解决链表、字符串、数组等问题(同向双指针VS对向双指针)
- Java 线程同步问题 生产者-消费者 算法实现 -Java学习笔记(29)
- 算法导论学习笔记-5.4 概率分析和指示器随机变量的应用-几个有趣的问题
- 算法学习笔记——利用栈解决实际问题- part 2
- SGI STL学习笔记(3):copy算法实现细节
- 3月31日学习笔记(6.0版本用Broadcast实现强制下线功能问题)
- QTP学习笔记(一):安装篇,解决QTP无法识别控件对象的问题