c ++中的3向mergesort stackoverflow错误

时间:2014-05-30 20:33:43

标签: c++ visual-c++ mergesort

嗨大家可以告诉我我的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
}

此时我想我已经完成了思考,任何答案/想法都会受到赞赏。

2 个答案:

答案 0 :(得分:0)

这是对您的代码的部分检查。我认为调试具有4个值的3路合并排序存在问题。您应该使用更多值,例如6或7。

空格不是StackOverflow的标签
我猜测缩进是因为您在代码中使用制表符并直接粘贴。您将要在下一篇文章中展开标签。

预编译标题
你的项目很大吗?更改标题或修改源代码时,是否会显着缩短构建时间?

我发现stdafx通常更麻烦,花费的时间解决了它导致的缺陷,因为它有一个预编译的头,从而抵消了任何潜在的节省。

函数原型应使用命名参数
您能否在mergemergeSort声明中说明不同参数的用途? 歧义会产生缺陷。 &#39;努夫说。

主要功能声明错误。
main函数始终向操作系统返回int。操作系统可以忽略它。

此机制使脚本文件可以执行您的程序并测试错误。

可读性可防止出现缺陷
投资运营商周围的空间。牺牲空间节省的时间可以忽略不计。通过易于阅读的代码节省的调试时间是巨大的,特别是当让其他人审查或检查您的代码时。

使用中间变量
中间变量有助于澄清您的程序。当您告诉编译器进行优化时,他们不会花费内存。在调试期间,他们可以帮助在计算过程中显示值。

读入矢量的典型习惯是:

  int value;
  cin >> value;
  s.push_back(value);

at方法可能存在溢出问题(或者至少您没有检查越界问题)。 push_back方法将导致向量根据需要展开。

有意义的变量名减少了缺陷
变量s没有意义。 original_valuesnumber_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将更快。