使用 C++ 多线程进行归并排序
给定一个未排序的整数数组。任务是使用通过多线程实现的合并排序技术对数组进行排序。
合并排序
合并排序是一种基于分治法的排序技术,我们将数组分成相等的两半,然后以排序的方式将它们合并。
实现合并排序的算法是
检查列表中是否有一个元素,然后返回该元素。
否则,递归地将数据分成两半,直到无法再分割为止。
最后,按排序顺序将较小的列表合并为新的列表。
多线程
在操作系统中,线程是负责执行部分任务的轻量级进程。线程共享资源并发执行任务。
多线程是多任务处理的一种实现,我们可以在单个处理器上运行多个线程来并发执行任务。它将单个应用程序中的特定操作细分为单独的线程。每个线程都可以并行运行。
例如:
输入减去int arr[] = {3, 2, 1, 10, 8, 5, 7, 9, 4}
输出减去排序后的数组为:1, 2, 3, 4, 5, 7, 8, 9, 10
解释减去我们给定的一个包含整数值的未排序数组。现在我们将使用多线程合并排序对数组进行排序。
输入减去 int arr[] = {5, 3, 1, 45, 32, 21, 50}
输出减去排序后的数组为:1, 3, 5, 21, 32, 45, 50
解释减去我们给定的一个包含整数值的未排序数组。现在我们将使用多线程合并排序对数组进行排序。
以下程序中使用的方法如下 −
我们将首先使用 C++ STL 中的 rand() 方法生成随机数。
创建一个 pthread_t 类型的数组,即 P_TH[thread_size]。
从 i 到 0 开始 FOR 循环,直到 i 小于线程的大小。在循环内部,调用 pthread_create(&P_TH[i], NULL, Sorting_Threading, (void*)NULL) 方法,使用给定的数组值创建线程。
将函数调用为:combine_array(0, (size / 2 - 1) / 2, size / 2 - 1)、combine_array(size / 2, size/2 + (size-1-size/2)/2, size - 1) 和 combing_array(0, (size - 1)/2, size - 1)
打印存储在整数类型 arr[] 中的排序数组。
函数内部:void* Sorting_Threading(void* arg)
将变量声明为 set_val ,设置为 temp_val++,first 设置为 set_val * (size / 4),end 设置为(set_val + 1) * (size / 4) - 1 并将 mid_val 赋值给 first + (end - first) / 2
检查 first 是否小于 end,然后调用 Sorting_Threading(first, mid_val)、Sorting_Threading(mid_val + 1, end) 和 combing_array(first, mid_val, end);
在函数 void Sorting_Threading(int first, int end) 内部
将变量声明为 mid_val,并将 first + (end - first) / 2
检查 first 是否小于 end,然后调用 Sorting_Threading(first, mid_val)、Sorting_Threading(mid_val + 1, end) 和 combing_array(first, mid_val, end)
在函数 void combing_array(int first, int mid_val, int end) 中
声明变量为 int* start 到 new int[mid_val - first + 1]、int* last 到 new int[end - mid_val]、temp_1 到 mid_val - first + 1、temp_2 到 end - mid_val、i、j、k 到 first。
从 i 到 0 开始 FOR 循环,直到 i 小于 temp_1。在循环内部,将 start[i] 设置为 arr[i + first]。
从 i 到 0 开始 FOR 循环,直到 i 小于 temp_2。在循环中,将 last[i] 设置为 arr[i + mid_val + 1]
将 i 设置为 j,使其为 0。当 i 小于 temp_1 且 j 小于 temp_2 时开始循环。在 while 循环中,检查 if start[i] 是否小于 last[j],并将 arr[k++] 设置为 start[i++]。否则,设置 arr[k++] = last[j++]
当 i 小于 temp_1 时开始循环,并将 arr[k++] 设置为 start[i++]。当 j 小于 temp_2 时开始循环,并将 arr[k++] 设置为 last[j++]
示例
#include <iostream> #include <pthread.h> #include <time.h> #define size 20 #define thread_size 4 using namespace std; int arr[size]; int temp_val = 0; void combine_array(int first, int mid_val, int end){ int* start = new int[mid_val - first + 1]; int* last = new int[end - mid_val]; int temp_1 = mid_val - first + 1; int temp_2 = end - mid_val; int i, j; int k = first; for(i = 0; i < temp_1; i++){ start[i] = arr[i + first]; } for (i = 0; i < temp_2; i++){ last[i] = arr[i + mid_val + 1]; } i = j = 0; while(i < temp_1 && j < temp_2){ if(start[i] <= last[j]){ arr[k++] = start[i++]; } else{ arr[k++] = last[j++]; } } while (i < temp_1){ arr[k++] = start[i++]; } while (j < temp_2){ arr[k++] = last[j++]; } } void Sorting_Threading(int first, int end){ int mid_val = first + (end - first) / 2; if(first < end){ Sorting_Threading(first, mid_val); Sorting_Threading(mid_val + 1, end); combine_array(first, mid_val, end); } } void* Sorting_Threading(void* arg){ int set_val = temp_val++; int first = set_val * (size / 4); int end = (set_val + 1) * (size / 4) - 1; int mid_val = first + (end - first) / 2; if (first < end){ Sorting_Threading(first, mid_val); Sorting_Threading(mid_val + 1, end); combine_array(first, mid_val, end); } } int main(){ for(int i = 0; i < size; i++){ arr[i] = rand() % 100; } pthread_t P_TH[thread_size]; for(int i = 0; i < thread_size; i++){ pthread_create(&P_TH[i], NULL, Sorting_Threading, (void*)NULL); } for(int i = 0; i < 4; i++){ pthread_join(P_TH[i], NULL); } combine_array(0, (size / 2 - 1) / 2, size / 2 - 1); combine_array(size / 2, size/2 + (size-1-size/2)/2, size - 1); combine_array(0, (size - 1)/2, size - 1); cout<<"Merge Sort using Multi-threading: "; for (int i = 0; i < size; i++){ cout << arr[i] << " "; } return 0; }
输出
如果我们运行上述代码,它将生成以下输出
Merge Sort using Multi-threading: 15 21 26 26 27 35 36 40 49 59 62 63 72 77 83 86 86 90 92 93