简体   繁体   English

合并排序-向量不排序

[英]Merge Sort - Vector not sorting

I'm trying to perform a merge sort on a std::vector<int> . 我正在尝试在std::vector<int>上执行合并排序。 Each int in the vector corresponds to an index in another vector std::vector<Node> . 向量中的每个int对应于另一个向量std::vector<Node>的索引。 Each node has a depth. 每个节点都有一个深度。 I am trying to sort based on depth. 我正在尝试根据深度进行排序。

I am using some merge sort code that I found. 我正在使用一些发现的合并排序代码。 It works fine using an array of integers, so I figured it would work fine in my code. 使用整数数组可以正常工作,因此我认为它可以在我的代码中正常工作。 Here is a shortened version of my code: 这是我的代码的简化版:

.h file: .h文件:

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

.cpp file: .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);
}

Note that the variable nodeList is just there because the depth method needs it. 请注意,变量nodeList就在那里,因为depth方法需要它。 The output looks like only the first half of the vector is touched. 输出看起来像只有向量的前半部分被触摸了。 No items on the second half of the vector ever get swapped. 向量后半部分的任何项目都不会交换。 I double checked to make sure the depths are correct, and that the correct things are being swapped. 我仔细检查以确保深度正确,并且正在交换正确的东西。 It just doesn't finish the job. 它只是没有完成工作。 Any ideas why? 有什么想法吗?

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

This does not get the number of elements in Log::a ! 这不会获得Log::a的元素数量! It gets the size (in bytes) of the std::vector type, which has nothing to do with the number of contained elements, then divides by the size of an element. 它获取std::vector类型的大小(以字节为单位),该大小与所包含元素的数量无关,然后除以元素的大小。 This gives you some garbage. 这给您带来一些垃圾。

This idiom is for arrays , and std::size is better, but not standard yet - you can easily write it yourself like this: 这个习惯用法是针对arrays的 ,并且std::size更好,但还不是标准的-您可以像这样轻松地自己编写它:

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

(There are more convoluted versions if you need it as a compile time constant.) (如果需要将其作为编译时间常数,则还有更多复杂的版本。)

Use Log::a.size(); 使用Log::a.size(); to get the size of a std::vector . 获得std::vector的大小。

(I may be missing other problems, but this one stands out.) (我可能会遗漏其他问题,但是这个问题很突出。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM