关于一个排序算法的问题

adventurelw 2009-03-26 06:03:24
实在是头大了。。。
关于快速排序的算法,个人觉得应该是对的,但就是对一个数组不行。。。。。。可能当局者迷,请求大家指点一下:
#include <iostream>

const int Size = 12;
const int size = 3;
int Midnum(int a, int b, int c);//选出三个数中中间那个
void SortQui(int a[], int begin, int end);//快速排序
int main()
{
using namespace std;
int ival[Size] = {18, 4, 20, 3, 65, 37, 45, 99, 32, 12, 2, 23};
cout << "Before sorted:\n";
for(size_t i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << endl << "After sorted:\n";
SortQui(ival, 0, Size);
for(size_t i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << "Done!" << endl;
return 0;
}

int Midnum(int a, int b, int c)
{
int temp[size] = {a, b, c};
int tempval;
for(size_t i = size - 1; i > 0; --i)
for(size_t j = 0; j < i; ++j)
{
if(temp[j] > temp[j + 1])
{
tempval = temp[j];
temp[j] = temp[j + 1];
temp[j + 1] = tempval;
}
}
return temp[2];
}


void SortQui(int a[], int begin, int end)
{
int low = begin, high = end - 1;
if(low < high)
{
int Keynum = Midnum(a[low], a[high], a[(low + high) / 2]);
if(Keynum == a[high])
{
a[high] = a[low];
a[low] = Keynum;
}
else if(Keynum == a[(low + high) / 2])
{
a[(low + high) / 2] = a[low];
a[low] = Keynum;
}
while(low < high)
{
while(low < high && a[high] >= Keynum)
--high;
a[low++] = a[high];
while(low < high && a[low] <= Keynum)
++low;
a[high--] = a[low];
}
a[low] = Keynum;
SortQui(a, begin, low);
SortQui(a, low + 1, end);
}
}

main中的那个数组测试没有问题,随便再写一个数组也行,比如:8, 4, 10, 3, 15, 23, 45, 99, 32, 12, 2, 17

但这个数组不行:int a[12] = {10, 18, 9, 2, 6, 13, 20, 15, 22, 14, 8, 4};
用这个算法排出来是:2 4 6 8 9 10 15 13 14 18 20 22
15那个位置的元素一定会在排到13前边,不管大小(和13比较),比如改成100,那么
结果就是:2 4 6 8 9 10 100 13 14 18 20 22
简直要晕倒了。。。。但我实在找不到哪里出问题了。。。。。。
...全文
156 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
夜色lion 2009-03-28
  • 打赏
  • 举报
回复
呵呵~!
其实LZ可以用 do while 循环的~!
我开始写的时候也是用while但是发现加的限制条件变多了~1
于是微 改成 di while 了

这样 代码可以变得简洁一点~!
feng4206yu 2009-03-27
  • 打赏
  • 举报
回复
不过如果想要排序更加精确一些,连续进行两次或者两次以上快速排序方法也可行....

for(size_t i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << endl << "After sorted:\n";
SortQui(ival, 0, Size);
for( i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << "Done!" << endl;
SortQui(ival, 0, Size);
for( i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << "Done!" << endl;

...并不是说结果正确,毕竟快速排序只是宏观上的范围排序,不能要求结果完全正确...
feng4206yu 2009-03-27
  • 打赏
  • 举报
回复
这是快速排序算法,看了一下,运行也没什么问题...还是算法本身的问题吧,快速排序不一定就是正确逻辑的排序算法...
adventurelw 2009-03-27
  • 打赏
  • 举报
回复
嗯,的确应该返回temp[1]
只是还是错误的,整个算法不知道怎么回事。。。。。。修改了之后竟然连原来能够正确排序的都无法正确排序了
按理说这个跟编译器应该是没有任何关系的。。。

ps:to fableboy兄,能不能麻烦说明一下哪里修改了。。。。
我是被这个弄崩溃了,恳请哪位老大再指教一下,我知道这个原理至少不复杂,但。。。。。。
adventurelw 2009-03-27
  • 打赏
  • 举报
回复
嗯,兄台的这个方法很好,一步一步模拟,我先去慢慢试试,试好了来给分。
adventurelw 2009-03-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 ypb362148418 的回复:]
建议你用Vector进行排序,这样快一些
[/Quote]
嗯,我知道STL有sort算法,因为是在学习算法,所以自己瞎写,呵呵。
adventurelw 2009-03-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 feng4206yu 的回复:]
我改了一下程序,结果正确了...但是是不是快速就不知道了...
C/C++ codevoidSortQui(inta[],intbegin,intend)
{intlow=begin, high=end-1;while(low<high)//第一处{intKeynum=Midnum(a[low], a[high], a[(low+high)/2]);if(Keynum==a[high])
{
a[high]=a[low];
a[low]=Keynum;
}elseif(Keynum==a[(low+high)/2])
{
a[(low+high)/2]=a[low];
a…
[/Quote]

我一个一个地返回low和high值,总算知道哪里出问题了,兄台这个怎么跟我原来那个还是一样,书上也是这样写的
主要是两步
a[low++] = a[high];
a[high--] = a[low];
这两步没加限定条件,所以前一个表达式会在low == high的时候使得low == high + 1
后一个会变本加利使得high最终比low小二,导致枢轴失效,所以给这两个表达式都加上if(low < high)就好了,虽然比较难看,但没有办法。
夜色lion 2009-03-27
  • 打赏
  • 举报
回复
前段时间也写过一遍~!
快速排序,分治的体现

现确定数组中的一个数字,然后从数组的第一个数,和最后一个数跟 你选定的那个数比~!然后自己安排是升序还是降序排列~!

若数组low的数字大于keynum,则low停止自加,high的数字小于keynum,high停止自加,交换这两个数字

直到 low>=high,退出!

个人意见:LZ可以自己写下算法,并且按自己写的程序模拟一遍~!但是在编译器上单步调试~!
这样帮助很大~!

我前段时间也是这样折磨出来的~!呵呵~!
kk927 2009-03-27
  • 打赏
  • 举报
回复
新手~进来学习的~
ypb362148418 2009-03-27
  • 打赏
  • 举报
回复
建议你用Vector进行排序,这样快一些
feng4206yu 2009-03-27
  • 打赏
  • 举报
回复
我改了一下程序,结果正确了...但是是不是快速就不知道了...

void SortQui(int a[], int begin, int end)
{
int low = begin, high = end - 1;
while(low < high) //第一处
{
int Keynum = Midnum(a[low], a[high], a[(low + high) / 2]);
if(Keynum == a[high])
{
a[high] = a[low];
a[low] = Keynum;
}
else if(Keynum == a[(low + high) / 2])
{
a[(low + high) / 2] = a[low];
a[low] = Keynum;
}
if(low < high) //第二处
{
while(low < high && a[high] >= Keynum)
--high;
a[low++] = a[high];
while(low < high && a[low] <= Keynum)
++low;
a[high--] = a[low];
}
a[low] = Keynum;
SortQui(a, begin, low);
SortQui(a, low, end);
}
}
jakqigle 2009-03-26
  • 打赏
  • 举报
回复

#include <iostream>

const int Size = 12;
const int size = 3;
int Midnum(int a, int b, int c);//选出三个数中中间那个
void SortQui(int a[], int begin, int end);//快速排序
int main()
{
using namespace std;
int ival[Size] = {18, 4, 20, 3, 65, 37, 45, 99, 32, 12, 2, 23};
cout < < "Before sorted:\n";
for(size_t i = 0; i < Size; ++i)
cout < < ival[i] < < " ";
cout < < endl < < "After sorted:\n";
SortQui(ival, 0, Size);
for(size_t i = 0; i < Size; ++i)
cout < < ival[i] < < " ";
cout < < "Done!" < < endl;
return 0;
}

int Midnum(int a, int b, int c)
{
int temp[size] = {a, b, c};
int tempval;
for(size_t i = size - 1; i > 0; --i)
for(size_t j = 0; j < i; ++j)
{
if(temp[j] > temp[j + 1])
{
tempval = temp[j];
temp[j] = temp[j + 1];
temp[j + 1] = tempval;
}
}
return temp[2];
}


void SortQui(int a[], int begin, int end)
{
int low = begin, high = end - 1;
if(low < high)
{
int Keynum = Midnum(a[low], a[high], a[(low + high) / 2]);
if(Keynum == a[high])
{
a[high] = a[low];
a[low] = Keynum;
}
else if(Keynum == a[(low + high) / 2])
{
a[(low + high) / 2] = a[low];
a[low] = Keynum;
}
while(low < high)
{
while(low < high && a[high] >= Keynum)
--high;
a[low++] = a[high];
while(low < high && a[low] <= Keynum)
++low;
a[high--] = a[low];
}
a[low] = Keynum;
SortQui(a, begin, low);
SortQui(a, low + 1, end);
}
}
lei_zhuyan 2009-03-26
  • 打赏
  • 举报
回复
[Quote=引用楼主 adventurelw 的帖子:]
#include <iostream>
#include <conio.h>
const int Size = 12;
const int size = 3;
int Midnum(int a, int b, int c);//选出三个数中中间那个
//什么叫做选出三个数中中间那个? 表述不清。是选出3个数大小排序后中间的那个吗?如果这样的话,函数应该返回temp[1].
.
void SortQui(int a[], int begin, int end);//快速排序

int main()
{
using namespace std;
int ival[Size] = {18, 4, 20, 3, 65, 37, 45, 99, 32, 12, 2, 23};
cout << "Before sorted:\n";
for(size_t i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << endl << "After sorted:\n";
SortQui(ival, 0, Size);
for(size_t i = 0; i < Size; ++i)
cout << ival[i] << " ";
cout << "Done!" << endl;
getch();
return 0;
}

int Midnum(int a, int b, int c)
{
int temp[size] = {a, b, c};
int tempval;
for(size_t i = size - 1; i > 0; --i)
for(size_t j = 0; j < i; ++j)
{
if(temp[j] > temp[j + 1])
{
tempval = temp[j];
temp[j] = temp[j + 1];
temp[j + 1] = tempval;
}
}
return temp[2];
}


void SortQui(int a[], int begin, int end)
{
int low = begin, high = end - 1;
if(low < high)
{
int Keynum = Midnum(a[low], a[high], a[(low + high) / 2]);
if(Keynum == a[high])
{
a[high] = a[low];
a[low] = Keynum;
}
else if(Keynum == a[(low + high) / 2])
{
a[(low + high) / 2] = a[low];
a[low] = Keynum;
}
while(low < high)
{
while(low < high && a[high] >= Keynum)
--high;
a[low++] = a[high];
while(low < high && a[low] <= Keynum)
++low;
a[high--] = a[low];
}
a[low] = Keynum;
SortQui(a, begin, low);
SortQui(a, low + 1, end);
}
}

[/Quote]

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧