OpenMP編寫奇偶排序


題目

奇偶排序及其並行化設計

定義

奇偶排序法的思路是在數組中重復兩趟掃描。第一趟掃描選擇所有的數據項對,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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM