合并排序 - 矢量不排序

时间:2015-12-17 11:05:10

标签: c++ sorting vector mergesort

我正在尝试对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就在那里,因为深度方法需要它。 输出看起来只有触摸向量的前半部分。矢量的后半部分没有任何项目被交换。我仔细检查以确保深度正确,并且正在交换正确的东西。它只是没有完成这项工作。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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的大小。

(我可能会错过其他问题,但这个问题很突出。)