【问题标题】:3-way mergesort stackoverflow error in c++C ++中的3路归并排序stackoverflow错误
【发布时间】:2014-07-20 17:01:33
【问题描述】:

大家好,谁能告诉我我的 3 路归并排序代码有什么问题?我写的代码只能对 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
}

此时我想我已经完成了思考,任何答案/想法将不胜感激。

【问题讨论】:

  • 从缩进来看,我猜} 不是你想的那样
  • 您的缩进有问题。考虑先修复它。
  • 我不会尝试阅读该代码;可能是stackoverflow.com/questions/12030683/… 的欺骗。
  • 这可能是因为您错误地定义了mainint main(void)main 函数总是返回 int
  • 我不明白。您使用 U 来不键入 you,但可以正确拼写较长的单词,例如 appreciated。如果你赶时间,你会尽量缩短所有的单词。如果您的目标是清晰地交流,您将使用you 而不是“U”。是的,不明白。

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


【解决方案1】:

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

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

预编译的标头
你的项目很大吗?当您更改标头或修改源代码时,它是否会显着减少构建时间?

我发现stdafx 通常比较麻烦,而且花费在解决它所导致的缺陷上的时间抵消了通过预编译头文件所带来的任何潜在节省。

函数原型应该使用命名参数
你能说出mergemergeSort声明中不同参数的用途吗?
模棱两可会滋生缺陷。 '纳夫说。

主函数声明错误。
main 函数总是向操作系统返回一个int。操作系统可以忽略它。

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

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

使用中间变量
中间变量有助于阐明您的程序。当您告诉编译器进行优化时,它们不会消耗内存。在调试期间,它们可以帮助在计算期间显示值。

读入向量的典型习语是:

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

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

有意义的变量名可减少缺陷
变量s 没有意义。 original_valuesnumber_container 之类的内容更具描述性。同样,变量名称长度与提高性能无关。可读的名称有助于减少注入的缺陷。

不检查cin的状态
如果我输入“Lion”以响应您的第二个提示,那么数组的第二个插槽中会出现什么?
不要相信用户,他们并不完美。

不要清屏
它可能包含有用的数据,例如输入的实际数字。因此,当您在调试时,想知道用户实际输入了什么,它就会丢失并永远消失。

为什么 cin.get 两次?
您在没有提示的情况下要求用户输入。两次。您的程序和用户之间的不良业力。

如果您想在收到特定字符之前忽略字符,请参阅cin.ignore。可能是这样的:

  cout << "Paused. Press Enter to continue.\n";
  cin.ignore(100000, '\n');  

幻数
在函数mergesort 中,您使用数字2 和3。为什么?他们的目的是什么?

冗余 cmets
大多数程序员意识到数学表达式中的“/”字符是除法。评论是多余的。

另外,为什么要除以 3?这是一个讨厌的数字。您是否意识到您正在执行 integer 除法并且您的产品将被截断?例如:1/3 == 2/3 == 0

使用调试器

最后,使用调试器可以更轻松、更快速地验证程序的许多功能。调试器允许您执行语句并查看变量值。您可以设置 断点 以在不同的地方停止执行。这是一项值得的教育投资,现在就开始吧。

【讨论】:

    【解决方案2】:

    “经典”的 3 路合并排序一次合并运行 3 次,在源数组和目标数组(或向量或列表)之间交替。代码需要执行最多 3 次比较,以便确定 3 次运行中每次运行的 3 个值中的“最小值”,然后将相应运行中的最小值移动到目标数组。代码还必须处理到达运行结束的情况,只剩下 2 次运行要合并,然后到达第二次运行结束的情况,在这种情况下,第三次运行的其余部分被移动到目标数组。

    对于基于 ram 的排序,我不确定这是否比普通的 2 路合并快。对于外部排序,具有多个设备或非常大的读取和写入,然后 k 路合并与 k 最多 12 或 16 会更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 2015-06-12
      相关资源
      最近更新 更多