【问题标题】:Divide and conquer merge sorting not working分而治之合并排序不起作用
【发布时间】:2019-01-04 13:25:51
【问题描述】:

这里是代码。我只是使用分而治之算法进行了合并排序,但它不起作用,我还没有找到原因。我将无序向量 0 和 vector.size() 传递给 mergeSort 函数。

#include <iostream>
#include <vector>
#include <algorithm>

template<typename T>
void directInsertion(std::vector<T>& vec, int start, int end);

template<typename T>
void merge (std::vector<T>& vec, int left, int middle, int right);

template<typename T>
void mergeSort(std::vector<T>& vec, int left, int right);

template<typename T>
void directInsertion(std::vector<T>& vec, int start, int end)
{
    T value = T();
    int i;
    int j;

    for(i = start + 1; i < end; ++i)
    {
        value = vec[i];
        for(j = i - 1; j >= 0 && !(vec[j] < value); --j)
            vec[j + 1] = vec[j];
        vec[j + 1] = value;
    }
}

template<typename T>
void mergeSort(std::vector<T>& vec, int left, int right)
{
    int length = right - left;

    if(length <= 3)
        directInsertion(vec, left, right);
    else
    {
        int middle = left + (length >> 1);
        mergeSort(vec, left, middle);
        mergeSort(vec, middle, right);
        merge(vec, left, middle, right);
    }
}

template<typename T>
void merge (std::vector<T>& vec, int left, int middle, int right)
{
    int length = right - left;
    int p = left;
    int q = middle + 1;

    std::vector<T> tmp;

    for(size_t l = 0; l < length; ++l) {
        if (p <= middle && (q >= right || vec.at(p) <= vec.at(q)))
            tmp.push_back(vec.at(p++));
        else
            tmp.push_back(vec.at(q++));
    }
    for(size_t l = 0; l < length; ++l)
        vec.at(left + l) = tmp.at(l);
}

void printMessage(bool passed, const char* message)
{
    if(passed)
        std::cout << message << "............... PASS" << std::endl;
    else
        std::cout << message << "............... FAIL" << std::endl;
}

void printVector(std::vector<int>& v)
{
    std::cout << "[";
    for(auto i: v)
        std::cout << " " << i << " ,";
    std::cout << "]";
}

int main()
{
    std::vector<int> v = {1, 2, 3, 4};
    std::vector<int> orderedVector = v;
    std::vector<int> aux;

    bool passed = true;

    do {
        aux = v;
        mergeSort(aux, 0, aux.size());
        if(aux != orderedVector)
        {
            printVector(aux);
            std::cout << " != ";
            printVector(orderedVector);
            std::cout << std::endl;
            passed = false;
        }
    } while(std::next_permutation(v.begin(), v.end()) && passed);

    printMessage(passed, "MERGE SORT");
}

【问题讨论】:

  • 这是一个应该调试解决的问题。使用您最喜欢的调试器(和/或)IDE,逐行执行代码,每次在让代码执行之前制定您的预期结果。如果这行代码的作用超出了您的预期,请在此处进行调查。像这样的调试对于程序员来说是一项至关重要的技能,所以要抓住这个机会!
  • 您是否使用调试器运行代码?将您的代码与the implementation here 进行比较。有什么不同?此外,声称某个功能正在运行,因此您不会多次发布该功能最终会浪费大量时间如果未发布的功能是有问题的功能。
  • @Repikas 如果我不能 100% 确定 directInsertion 是否正常工作,我会发布它 -- 如果我为每个未发布“工作代码”的帖子都有一美元“是实际的问题,我会成为一个有钱人。请发帖minimal reproducible example
  • 我修复了缺失的包含、缺失的打印函数,并重新排序了函数以便它可以运行。你的例子应该运行而我不必这样做。我的矢量索引超出范围。我不是说在哪里,因为你在调试时应该得到相同的结果,这对你来说会更有用。
  • 也避免名称冲突。 “向量”不是变量名的明智选择。但是很好的测试用例——我建议你把它做得尽可能小,但仍然会出现错误,所以它很容易调试。

标签: c++ algorithm sorting debugging mergesort


【解决方案1】:

可能还有其他问题,但是这行需要修复:

        mergeSort(vec, middle + 1, right);

改为

        mergeSort(vec, middle, right);

我还建议使用名称 begin 和 end 而不是 left 和 right,以符合用于向量迭代器的命名约定,并且因为“右”迭代器或索引指向向量的“结束”或数组,数组最后一个元素之后的 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 2013-02-05
    • 2012-09-08
    • 1970-01-01
    • 2013-07-02
    • 2020-07-23
    • 2015-04-08
    相关资源
    最近更新 更多