0

我想用 C++ 和向量实现归并排序(考虑到输入的整数个数是未知的)。我试图通过维基百科实现基于自下而上的实现思想:http ://en.wikipedia.org/wiki/Merge_sort 。我出来了以下代码。它可以通过编译,但在输入数字时会死机。我不知道这里出了什么问题。

#include<iostream>
#include<vector>
using namespace std;

void BottomUpMerge(vector<int>, vector<int>::iterator, vector<int>::iterator, vector<int>::iterator, vector<int>);

void BottomUpSort(int n, vector<int> A, vector<int> B)
{
  int width;

  /* Each 1-element run in A is already "sorted". */

  /* Make successively longer sorted runs of length 2, 4, 8, 16... until whole array is sorted. */
  for (width = 1; width < n; width = 2 * width){
    vector<int>::iterator leftstart;

    /* Array A is full of runs of length width. */
    for (leftstart = A.begin(); leftstart <= A.end(); leftstart = leftstart + 2 * width){
        /* Merge two runs: A[i:i+width-1] and A[i+width:i+2*width-1] to B[] */
        /* or copy A[i:n-1] to B[] ( if(i+width >= n) ) */
        vector<int>::iterator rightstart;
        vector<int>::iterator rightend;
        if(leftstart+width >= A.end()){
            rightstart = A.end();
        }
        else{
            rightstart = leftstart+width;
        }
        if(leftstart+2*width >= A.end()){
            rightend = A.end();
        }
        else{
            rightend = leftstart+2*width;
        }

        BottomUpMerge(A, leftstart, rightstart, rightend, B);
    }

    /* Now work array B is full of runs of length 2*width. */
    /* Copy array B to array A for next iteration. */
    /* A more efficient implementation would swap the roles of A and B */
    A = B;
    /* Now array A is full of runs of length 2*width. */
    }
}

void BottomUpMerge(vector<int> A, vector<int>::iterator iLeft, vector<int>::iterator iRight, vector<int>::iterator iEnd, vector<int> B)
{
  vector<int>::iterator i0 = iLeft;
  vector<int>::iterator i1 = iRight;
  vector<int>::iterator j = B.begin() + distance(iLeft, A.begin()); //iterator for vector B

  /* While there are elements in the left or right lists */
  for (; j != B.end(); j++){
    /* If left list head exists and is <= existing right list head */
    if (i0 < iRight && (i1 >= iEnd || *i0 <= *i1)){
        *j = *i0;
        i0 = i0 + 1;
    }
    else{
        *j = *i1;
        i1 = i1 + 1;
    }
  }
}


int main(){
    int input;
    vector<int> numbers;    //input vector of numbers

    cout << "Please input the numbers to be sorted:" << endl;
    while(cin>>input){
        numbers.push_back(input);
    }

    int length = numbers.size();
    vector<int> sorted = numbers;   //work vector ensure has the same size of the original vector

    BottomUpSort(length, numbers, sorted);

    vector<int>::iterator it;
    for(it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << (*it) << '\n';
    }

    system("pause");
    return 1;
}
4

1 回答 1

0

看这里:

BottomUpMerge(A, leftstart, rightstart, rightend, B);
...

void BottomUpMerge(vector<int> A, vector<int>::iterator iLeft, ...)
{
  ...

您正在按值传递向量,这意味着BottomUpMerge正在处理它们的副本。但是迭代器仍然指向原件,并且随之而来的是欢闹。通过引用传递向量,至少其中一些问题应该消失。

(You should have discovered this when you were testing this function, before you wrote all of the surrounding code. Never add to code that doesn't work.)

于 2013-07-02T20:57:28.230 回答