C ++中Mergesort的问题

时间:2010-04-19 17:13:39

标签: c++ merge mergesort

vector<int>& mergesort(vector<int> &a) {
    if (a.size() == 1) return a;
    int middle = a.size() / 2;
    vector<int>::const_iterator first = a.begin();
    vector<int>::const_iterator mid = a.begin() + (middle - 1);
    vector<int>::const_iterator last = a.end();
    vector<int> ll(first, mid);
    vector<int> rr(mid, last);

    vector<int> l = mergesort(ll);
    vector<int> r = mergesort(rr);
    vector<int> result;
    result.reserve(a.size());
    int dp = 0, lp = 0, rp = 0;

    while (dp < a.size()) {
        if (lp == l.size()) {
            result[dp] = (r[rp]);
            rp++;
        } else if (rp == r.size()) {
            result[dp] = (l[lp]);
            lp++;
        } else if (l[lp] < r[rp]) {
            result[dp] = (l[lp]);
            lp++;
        } else {
            result[dp] = (r[rp]);
            rp++;
        }
        dp++;
    }
    a = result;
    return a;
}

它正确编译但在执行时,我得到了:

  

此应用程序已请求   运行时以不寻常的方式结束它。

这是一个奇怪的错误。

代码是否存在根本错误?

4 个答案:

答案 0 :(得分:7)

result.reserve(a.size())只会影响矢量的 容量 ,而不会影响 尺寸 。 (向量的容量告诉向量可以增长到哪个大小,而无需重新分配和复制所有成员。基本上它只用于优化目的。)您无法访问保留之后result中的所有成员,因为没有任何成员。使用result.push_back(...)代替result[dp] = ...result.resize(a.size())代替result.reserve(a.size())

我认为前者可能更有效。

答案 1 :(得分:5)

一个问题是使用reserve()(使用resize()或使用push_back()追加项目而不是访问索引)。


if (a.size() == 1) return a;
int middle = a.size() / 2;
vector<int>::const_iterator first = a.begin();
vector<int>::const_iterator mid = a.begin() + (middle - 1);
vector<int>::const_iterator last = a.end();
vector<int> ll(first, mid);
vector<int> rr(mid, last);

这可能是另一个问题。如果大小为2,则ll最终将成为空向量,并且此函数似乎不会处理此问题。似乎没有太多理由从中间减去1。


您可能还在远远超出需要复制内容:您不应该需要lr向量(因为它们只是ll的副本和rr),同样我认为您不需要result向量,因为您可以将合并后的结果直接写回a

答案 2 :(得分:1)

reserve()不会更改向量中的内容量。你已经创建了一个空向量,为它保留了一定的大小,然后用v [i] = x;这不是向量的有效使用,因为向量中仍然没有任何第i个元素。

改为使用resize()。

答案 3 :(得分:0)

错误消息非常不清楚,因为当异常未处理时,它是VC ++的标准消息。你可以在main中添加一个try-catch-clock来获取异常和一个更有意义的错误:

int main() {
    try {
        // do main stuff here
    }
    catch ( std::exception & e ) {
        std::cout << e.what() << std::endl;
    }
}

这是针对命令行的。如果您的应用程序没有,请使用消息框或将错误写入日志文件。

关于代码中的问题,所有其他答案似乎都是正确的。