嗨大家可以告诉我我的3路mergesort代码有什么问题吗?我写的代码只能排序4个数字,如果你给它超过4个数字(通过改变大小)它最终会出现堆栈溢出错误,这里是代码:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int size=4;
vector <int> s(size);
void merge(int,int,int);
void mergesort(int,int);
int main(){
for(int i=0;i<size;i++){
cout<<"enter number "<<i+1<<":";
cin>>s.at(i);
}
system("CLS");
cout<<"here are the unsorted numbers:\n";//prints the input values so U can see'em
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
mergesort(0,size-1);//calls mergesort
cout<<"\nhere are the sorted numbers:\n";
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
cin.get();
cin.get();
return 0;
}
void merge(int low,int one_third,int high){
int i=low;
int j=one_third+1;
int k=0;
int length=(high-low)+1;
vector <int> u(length,0);
if(k<length){
while((i<=one_third)&&(j<=high)){
if(s.at(i)<=s.at(j)){
u.at(k)=s.at(i);
i++;
k++;
}//end for
else{
u.at(k)=s.at(j);
j++;
k++;
}//end elseif
}//end while
if(j>high)
while(i<=one_third)
{
u.at(k)=s.at(i);
i++;
k++;
}
if(i>one_third)
while(j<=high)
{
u.at(k)=s.at(j);
j++;
k++;
}
for(int n=low;n<k;n++)
s.at(n)=u.at(n);
}
}//end if
void mergesort(int low,int high){
if(low<high){
int one_third=(high-low)/3;//division,it's 3-way mergesort so obviously it's divided by 3
int two_third=2*one_third;
mergesort(low,one_third);
mergesort(one_third+1,two_third);
mergesort(two_third+1,high);
merge(low,one_third,two_third);
merge(low,two_third,high);
}//end if
}
此时我想我已经完成了思考,任何答案/想法都会受到赞赏。
答案 0 :(得分:0)
这是对您的代码的部分检查。我认为调试具有4个值的3路合并排序存在问题。您应该使用更多值,例如6或7。
空格不是StackOverflow的标签
我猜测缩进是因为您在代码中使用制表符并直接粘贴。您将要在下一篇文章中展开标签。
预编译标题
你的项目很大吗?更改标题或修改源代码时,是否会显着缩短构建时间?
我发现stdafx
通常更麻烦,花费的时间解决了它导致的缺陷,因为它有一个预编译的头,从而抵消了任何潜在的节省。
函数原型应使用命名参数
您能否在merge
和mergeSort
声明中说明不同参数的用途?
歧义会产生缺陷。 &#39;努夫说。
主要功能声明错误。
main
函数始终向操作系统返回int
。操作系统可以忽略它。
此机制使脚本文件可以执行您的程序并测试错误。
可读性可防止出现缺陷
投资运营商周围的空间。牺牲空间节省的时间可以忽略不计。通过易于阅读的代码节省的调试时间是巨大的,特别是当让其他人审查或检查您的代码时。
使用中间变量
中间变量有助于澄清您的程序。当您告诉编译器进行优化时,他们不会花费内存。在调试期间,他们可以帮助在计算过程中显示值。
读入矢量的典型习惯是:
int value;
cin >> value;
s.push_back(value);
at
方法可能存在溢出问题(或者至少您没有检查越界问题)。 push_back
方法将导致向量根据需要展开。
有意义的变量名减少了缺陷
变量s
没有意义。 original_values
或number_container
之类的内容更具描述性。同样,变量名称长度与提高性能无关。可读名称有助于减少注入的缺陷。
未检查cin
的状态
如果我进入&#34; Lion&#34;为了响应你的第二个提示,数组的第二个插槽中会有什么内容?
不要相信用户,他们并不完美。
不要清除屏幕
它可能包含有用的数据,例如输入的实际数字。因此,当您进行调试并想知道用户实际键入的内容时,它将会丢失并永远消失。
为什么cin.get两次?
您是在没有提示的情况下要求用户输入的。两次。您的程序和用户之间的坏Karma。
如果要在收到特定字符之前忽略字符,请参阅cin.ignore
。也许是这样的事情:
cout << "Paused. Press Enter to continue.\n";
cin.ignore(100000, '\n');
幻数
在函数mergesort
中,您使用数字2和3.为什么?他们的目的是什么?
冗余评论
大多数程序员都意识到&#39; /&#39;数学表达式中的字符是除法。评论是多余的。
另外,为什么除以3?这是一个令人讨厌的数字。您是否意识到您正在执行整数除法并且您的产品将被截断?例如:1/3 == 2/3 == 0
。
最后,通过使用调试器,可以更轻松,更快地验证您的许多程序的功能。调试器允许您执行语句并查看变量值。您可以设置断点以停止在不同位置执行。这是一项有价值的教育投资,从现在开始。
答案 1 :(得分:0)
A&#34;经典&#34; 3路合并排序合并一次运行3个,在源和目标数组(或矢量或列表)之间交替。代码需要执行最多3次比较,以确定最小的&#34;从3次运行中的每次运行中获取3个值,然后将最小值从其相应的运行移动到目标阵列。代码还必须处理到达运行结束的情况,只剩下2次运行进行合并,然后是第二次运行结束的情况,在这种情况下,第三次运行的其余部分被移动到目标数组。
对于基于ram的排序,我不确定这比普通的2路合并更快。对于具有多个设备或非常大的读取和写入的外部排序,k方式与k合并到12或16将更快。