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]就是,现在是乱序的。

猜你喜欢

转载自www.cnblogs.com/caijiyang/p/12941344.html