咱们都知道冒泡排序的串行算法的实现,很是简单,两个for循环便可实现,那么并行算法又如何实现呢?算法
先介绍一下算法思想。windows
(1)串行算法思想:从左至右依次比较相邻的两个数据,若是左边的数比右边的数大,则交换,这样通过一轮变换后,最大的数据就会移到最右边;而后第二轮只需比较剩余的n-1个数便可,找到次最大的数据;依次类推,直到将这n个数据排好序。数组
下面是串行冒泡排序算法的核心代码:函数
for(i=0;i<n-1;i++) //n-1轮 { for(j=0;j<n-i-1;j++) { if(array[j]>array[j+1]) { tmp=array[j]; array[j]=array[j+1]; array[j+1]=tmp; } } }
(2)并行算法思想:并行算法能够使用奇偶排序是冒泡排序的并行化版本,其思想就是将冒泡排序的每轮操做分解成奇数位和偶数位上的比较、交换,且互不干扰,因此能够并行化。线程
//#include"stdafx.h" #include<stdio.h> #include<malloc.h> #include<windows.h> int* array; bool flag=false; void Exchange(int* j) //比较并交换相邻元素 { int b; int k=*((int* )j); if(array[k]>array[k+1]) { b=array[k]; array[k]=array[k+1]; array[k+1]=b; flag=true; } } void Parallel_BubbleSort(int length) //并行冒泡排序主体 { int i,j; int *tag=(int* )malloc(sizeof(int)*length); for(i=0;i<length;i++) tag[i]=i; HANDLE* h=(HANDLE* )malloc(sizeof(HANDLE)*(length/2)); for(i=0;i<length;i++) { if(i%2==0) //比较偶数位 { for(j=0;j<length-1;j+=2) //每循环一次,就建立一个交换线程 { //建立线程函数 h[j/2]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Exchange, &tag[j], //不能直接传j,j值会改变 0, NULL); printf("建立偶数线程\n"); } WaitForMultipleObjects((length-1)/2,h,TRUE,INFINITE); } else //比较奇数位 { for(j=1;j<length-1;j+=2) { h[(j-1)/2]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Exchange, &tag[j], 0, NULL); printf("建立奇数线程\n"); } WaitForMultipleObjects(length/2,h,TRUE,INFINITE); if(!flag) //当一次偶一次奇以后,才能跳出 break; flag=false; } } } void main() { int i,length; printf("请输入数组长度:"); scanf("%d",&length); if(length<0) printf("输入错误!"); else { array=(int* )malloc(sizeof(int)*length); //建立动态数组 printf("请输入数组的值:"); for(i=0;i<length;i++) { scanf("%d",&array[i]); } Parallel_BubbleSort(length); for(i=0;i<length;i++) printf("%d ",array[i]); printf("\n"); } }
上述代码,为了提升算法效率,增长了一个标志位flag,当最后数组数据已经排好序,就跳出循环,而非循环最大的次数。code
在两个算法先后加上clock()计时函数,比较运行时间发现:并行的奇偶排序算法所花费的时间比串行算法还要多,由于它建立线程很是频繁,所消耗的时间相对来讲比较大。排序