实现归并排序c++

implementing merge sort c++

本文关键字:c++ 归并排序 实现      更新时间:2023-10-16

嗨,我正试图在我传递到函数的向量上实现合并排序。这是我的代码,它不排序列表,但我不确定什么是错的。当我输出原始向量和排序后的向量时,两者之间存在一些差异,但它仍然没有排序。

void BestFit::findBest(){
    vector<double> distances;
    vector<double> sorted;
    distances = getDistance(0);
    printDistance(distances);
    sorted = sortDistance(distances);
    printDistance(sorted);
}
vector<double> BestFit::sortDistance(vector<double> distances){
    int mid = distances.size()/2;
    vector<double> left;
    vector<double> right;
    if(distances.size() > 1){
        for(int i = 0; i < mid; i++){
            left.push_back(distances[i]);
        }
        for(int i = mid; i < distances.size(); i++){
            right.push_back(distances[i]);
        }
        return sortDistanceHelp(left, right);
    }else{
        return distances;
    }
}
vector<double> BestFit::sortDistanceHelp(vector<double> left, vector<double> right){
    vector<double> result;
    if(left.size() > 1){
        left = sortDistance(left);
    }else if(right.size() > 1){
        right = sortDistance(right);
    }
    int count = 0;
    int left_count = 0;
    int right_count = 0;
    while(count < (left.size() + right.size())){
        if(left_count < left.size() && right_count < right.size()){
            if(left[left_count] <= right[right_count]){
                result.push_back(left[left_count]);
                left_count++;
            }else{
                result.push_back(right[right_count]);
                right_count++;
            }
        }else if(left_count < left.size()){
            result.push_back(left[left_count]);
            left_count++;
        }else{
            result.push_back(right[right_count]);
            right_count++;
        }
        count++;
    }
    return result;
}

这是未排序和排序的距离向量的输出。

无序:

距离:0.679371距离:1.263918距离:1.575268距离:0.117904距离:3.851347距离:2.317885距离:0.899686距离:3.916363距离:1.513004距离:0.446430

排序:

距离:0.679371距离:1.263918距离:1.575268距离:0.117904距离:2.317885距离:0.899686距离:3.851347距离:3.916363距离:1.513004距离:0.446430

我很确定这就是问题所在。In sortDistanceHelp():

if(left.size() > 1){
    left = sortDistance(left);
}else if(right.size() > 1){ //<<<===== ELSE SHOULD NOT BE HERE
    right = sortDistance(right);
}

应该是这样的:

if(left.size() > 1)
    left = sortDistance(left);
if(right.size() > 1)
    right = sortDistance(right);

剩下的部分只是一个简单的合并算法,您可以根据自己的目的使用它来利用迭代器。这是我能想到的最简单的合并算法。它依赖于您的数据类型来支持operator <(),以及operator =()

template<typename ForwardIterator, typename OutputIterator>
void mergelists
(
    ForwardIterator first1,     // starting iterator of first sequence
    ForwardIterator last1,      // ending iterator of first sequence
    ForwardIterator first2,     // starting iterator of second sequence
    ForwardIterator last2,      // ending iterator of second sequence
    OutputIterator out1)        // output iterator for results
{
    while (first1 != last1 && first2 != last2)
    {
        // note the opposing less-comparison. equtes to (i1 <= i2)
        while (first1 != last1 && !(*first2 < *first1))
            *out1++ = *first1++;
        if (first1 != last1)
        {
            while (first2 != last2 && *first2 < *first1)
                *out1++ = *first2++;
        }
    }
    // doesn't really matter which one finished first
    //  only one of these will put one or more final
    //  nodes into the sequence.
    while (first1 != last1)
        *out1++ = *first1++;
    while (first2 != last2)
        *out1++ = *first2++;
}

与接受起始迭代器和大小的通用归并排序算法相结合,得到:

// general mergesort algorithm
template <typename Iterator>
void mergesort(Iterator first, size_t d)
{
    typedef typename std::iterator_traits<Iterator>::value_type value_type;
    Iterator last = first + d;
    size_t n = d/2;
    if (n == 0)
        return;
    if (n > 1) // no single elements
        mergesort(first, n);
    if (d > 1) // no single elements
        mergesort(first+n, d-n);
    // merge back into local sequence
    std::vector<value_type> vals;
    vals.reserve(d);
    mergelists(first, first+n, first+n, last, back_inserter(vals));
    // and copy into where it all began
    std::copy(vals.begin(), vals.end(), first);
}

下面是一个随机填充向量的例子:

int main()
{
    srand((unsigned)time(0));
    vector<int> data;
    // fill a vector with random junk.
    generate_n(back_inserter(data), 20, []() { return std::rand() % 99+1;});
    copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    mergesort(data.begin(), data.size());
    copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    return 0;
}

示例运行I

54 75 14 59 69 18 65 40 52 77 65 43 87 80 99 44 81 40 70 37 
14 18 37 40 40 43 44 52 54 59 65 65 69 70 75 77 80 81 87 99 

Sample Run II

53 91 27 29 47 31 20 90 12 18 16 75 61 94 60 55 66 44 35 26 
12 16 18 20 26 27 29 31 35 44 47 53 55 60 61 66 75 90 91 94