合并排序 - 向量不排序

Posted

技术标签:

【中文标题】合并排序 - 向量不排序【英文标题】:Merge Sort - Vector not sorting 【发布时间】:2015-12-17 11:05:10 【问题描述】:

我正在尝试对std::vector<int> 执行合并排序。向量中的每个 int 对应于另一个向量 std::vector<Node> 中的一个索引。每个节点都有一个深度。我正在尝试根据深度进行排序。

我正在使用我找到的一些合并排序代码。使用整数数组可以正常工作,所以我认为它可以在我的代码中正常工作。这是我的代码的缩短版本:

.h 文件:

class Log
public:
    static std::vector<int> a;
;

.cpp 文件:

std::vector<int> Log::a;

int getNodeDepth (int index, std::vector<cv::ml::DTrees::Node::Node> nodeList, std::vector<int> treeList) 
    //returns the node's depth


void exchange(int i, int j) 
    int t = Log::a[i];
    Log::a[i] = Log::a[j];
    Log::a[j] = t;


void compare(int i, int j, std::vector<cv::ml::DTrees::Node::Node> nodeList) 
    if (getNodeDepth(nodeList[Log::a[i]], nodeList) > (getNodeDepth(nodeList[Log::a[j]], nodeList)))
    exchange(i, j);


/**
 * lo is the starting position and
 * n is the length of the piece to be merged,
 * r is the distance of the elements to be compared
 */
void oddEvenMerge(int lo, int n, int r, std::vector<cv::ml::DTrees::Node::Node> nodeList) 
    int m = r * 2;
    if (m < n) 
        oddEvenMerge(lo, n, m, nodeList); // even subsequence
        oddEvenMerge(lo + r, n, m, nodeList); // odd subsequence
        for (int i = lo + r; i + r < lo + n; i += m)
            compare(i, i + r, nodeList);
     else
        compare(lo, lo + r, nodeList);


/**
 * sorts a piece of length n of the array
 * starting at position lo
 */
void oddEvenMergeSort(int lo, int n, std::vector<cv::ml::DTrees::Node::Node> nodeList) 
    if (n > 1) 
        int m = n / 2;
        oddEvenMergeSort(lo, m, nodeList);
        oddEvenMergeSort(lo + m, m, nodeList);
        oddEvenMerge(lo, n, 1, nodeList);
    


int mergeSort(std::vector<int> treeList, std::vector<cv::ml::DTrees::Node::Node> nodeList) 
    Log::a = treeList;
    int i, n = sizeof(Log::a) / sizeof(Log::a[0]);
    for (i = 0; i < n; i++)
        std::cout << std::setw(3) << Log::a[i];
    std::cout << std::endl;
    oddEvenMergeSort(0, n, nodeList);
    //print sorted list
    for (i = 0; i < Log::a.size(); i++)
        std::cout << Log::a[i] << "  *   ";
    std::cout << std::endl;

    return(0);

请注意,变量nodeList 就在那里,因为深度方法需要它。 输出看起来像只触摸了矢量的前半部分。向量后半部分的任何项目都不会被交换。我再次检查以确保深度是正确的,并且正在交换正确的东西。它只是没有完成工作。任何想法为什么?

【问题讨论】:

为什么不使用 std::sort ? cplusplus.com/reference/algorithm/sort我想你已经有比较方法了。 “我正在使用我找到的一些合并排序代码。” - 你在哪里找到的?你不能只使用你在网上找到的代码而不注明出处,并遵守它列出的任何许可证。 (虽然为了保持问题简短而删减它可能是合理的,但它必须在你的真实代码中,你应该从这里链接到它。) 是否应该通过引用而不是值来传递nodeList? 【参考方案1】:

sizeof(Log::a) / sizeof(Log::a[0]);

这没有得到Log::a中的元素个数!它获取std::vector 类型的大小(以字节为单位),这与包含的元素的数量无关,然后除以元素的大小。这会给你一些垃圾。

这个成语适用于数组std::size 更好,但还不是标准的——你可以像这样轻松地自己写:

template <typename T, std::size_t N>
std::size_t arraySize(T (&)[N])

    return N;

(如果你需要它作为编译时间常数,还有更复杂的版本。)

使用Log::a.size(); 获取std::vector 的大小。

(我可能遗漏了其他问题,但这个问题很突出。)

【讨论】:

谢谢你,我做了这个改变,现在它通过了所有的成员,但顺序仍然是错误的。结果最终也会覆盖值,因此存在重复项。我不知道为什么它在常规 int 数组上运行良好时表现如此奇怪。

以上是关于合并排序 - 向量不排序的主要内容,如果未能解决你的问题,请参考以下文章

合并排序的合并操作不使用 C++ 向量

将两个排序向量合并到一个排序向量中

C++ 合并和排序 2 个向量

合并 K 个排序数组/向量的复杂性

向量下标超出范围 C++ 合并排序

使用向量进行合并排序 (int) C++