マージソートのマルチスレッド実装(C ++)

マルチスレッド分析を使用したマージソート

マージソートは2つのステップに分かれています。

  1. アレイを連続的に半分に分割します(下向きのプロセス)。
  2. 隣接するサブアレイをマージします(上向きのプロセス)。
    分割されたサブアレイの場合、それらは互いに独立しており、リソースは共有されないため、複数のスレッドを使用しても安全です。(マージする前に、2つの子スレッドを完了するまで実行する必要があります。つまり、joinは、2つの子スレッドが完了するまで実行されるまで現在のスレッドをブロックします)

C ++コード

#include <iostream>
#include <thread>
#include <vector>
#include <functional>

using namespace std;

void merge(vector<int>& nums, int s, int mid, int e){
    
    
    vector<int> lnums, rnums; // lnums, rnums为两个子序列,nums用于存放合并后的序列
    for(int i = s; i <= e; i++){
    
    
        if(i <=mid){
    
    
            lnums.push_back(nums[i]);
        }else{
    
    
            rnums.push_back(nums[i]);
        }
    }

    int l = 0, r = 0, k = s;
    // 比较两个指针(l和r)所指向的元素,选择相对小的元素(升序)放入到合并空间,
    // 并移动指针到下一位置,直到其中一个指针超出序列尾
    while(l < lnums.size() && r < rnums.size()){
    
    
        if(lnums[l] < rnums[r]){
    
    
            nums[k++] = lnums[l++];
        }else{
    
    
            nums[k++] = rnums[r++];
        }
    }
    // 将另一序列剩下的所有元素直接复制到合并序列尾
    while(l < lnums.size()){
    
    
        nums[k++] = lnums[l++];
    }
    while(r < rnums.size()){
    
    
        nums[k++] = rnums[r++];
    }
}

void mergeSort(vector<int>& nums, int s, int e){
    
    
    if(s >= e){
    
    
        return;
    }

    int mid = (s + e)/2;
    // 向下拆分,独立进行,可以多线程
    // 疑问:为什么要用bind(),thread t1(mergeSort,std::ref(nums),s,mid);编译错误?
    // std::bind默认采用参数的拷贝而不是引用,用std::ref转化为引用
    thread t1(std::bind(mergeSort,std::ref(nums),s,mid));
    thread t2(std::bind(mergeSort,std::ref(nums),mid+1,e));
    t1.join();
    t2.join();
    // mergeSort(nums,s,mid);
    // mergeSort(nums,mid+1,e);
    // 向上合并
    merge(nums,s,mid,e);
}

vector<int> sortArray(vector<int>& nums) {
    
    
    // 归并排序
    vector<int> arr = nums; // 为了不改变原数组
    mergeSort(arr,0,arr.size()-1);
    return arr;
}

int main(){
    
    
    vector<int> nums{
    
    10,9,8,7,2,3,4,5,6,1,0}, re;
    re = sortArray(nums);
    for(int num:re){
    
    
        cout << num << " ";
    }
    cout << endl;
    return 0;
}

おすすめ

転載: blog.csdn.net/XindaBlack/article/details/106989305
おすすめ