題目
奇偶排序及其並行化設計
定義
奇偶排序法的思路是在數組中重復兩趟掃描。第一趟掃描選擇所有的數據項對,a[j]和a[j+1],j是奇數(j=1, 3, 5……)。如果它們的關鍵字的值次序顛倒,就交換它們。第二趟掃描對所有的偶數數據項進行同樣的操作(j=0,2, 4,6……)。重復進行這樣兩趟的排序直到數組全部有序。
奇偶交換總是成對出現,這樣才能保證比較和交換涉及到數組中的每一個元素。
分析
奇偶排序可以看做是冒泡排序的升級版,但冒泡排序中每個元素既可能與前面的元素交換,也可能與后面的元素交換,奇偶排序消除了這種數據的相關性,所以可以實現並行化設計。
#include "pch.h" #include <iostream> #include "stdio.h" #include "omp.h" using namespace std; int main() { bool flag = true,change=true; int n; cin >> n; int *a =new int[n]; for (int i = 0; i < n; i++) { cin >> a[i]; } //設定並行線程數 omp_set_num_threads(n / 2); //flag為true或者 change為false(即要進行奇排序時)進入循環 while (flag || !change) { flag = false; if (change) //偶循環 { //並行for開始 #pragma omp parallel for for (int i = 0; i < n-1; i += 2) { if (a[i] > a[i + 1]) { flag = true; int temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } else //奇循環 { //並行for開始 #pragma omp parallel for for (int i = 1; i < n-1; i += 2) { if (a[i] > a[i + 1]) { flag = true; int temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } //奇變偶 偶變奇 if (change) { change = false; } else { change = true; } } for (int i = 0; i < n; i++) { cout<<a[i]<<" "; } return 0; }
注意細節,假如上一輪發生數據交換或者變為奇排序,則繼續循環。
發生數據交換進入循環很好理解。
奇循環條件,則是因為一開始進行的是偶循環,為了保證可以進行一輪偶循環和奇循環之后才結束,因為不存在一個數列,奇循環和偶循環都不發生數據交換的情況下是亂序。
但是存在數列,偶循環下不發生數據交換,奇循環下發生數據循環。[1,2,1,2,1,2]就是,現在是亂序的。
最近上課發現可以在一輪里面同時進行奇偶排序就行可以簡化代碼
int main() { bool flag = true; int n; cin >> n; int *a =new int[n]; for (int i = 0; i < n; i++) { cin >> a[i]; } //設定並行線程數 omp_set_num_threads(n / 2); //flag為true或者 change為false(即要進行奇排序時)進入循環 while (flag) { flag = false; //並行for開始 #pragma omp parallel for for (int i = 0; i < n-1; i += 2) { if (a[i] > a[i + 1]) { flag = true; int temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } //並行for開始 #pragma omp parallel for for (int i = 1; i < n-1; i += 2) { if (a[i] > a[i + 1]) { flag = true; int temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } for (int i = 0; i < n; i++) { cout<<a[i]<<" "; } return 0; }