奇偶排序

在《java高并发程序设计》一书中看到关于一种并行算法排序方法:奇偶排序。结合书上与网上的各项资料,在这里按自己的理解做下梳理。

介绍

冒泡排序:是串行算法,在每次迭代过程中,对于每个元素可能与前面元素交换,也可能和后面的元素交换,数据的相关性比较强很难直接改成并行算法。

奇偶排序:或奇偶换位排序,或砖排序,是一种相对简单的排序算法,最初发明用于有本地互连的并行计算。这是与冒泡排序特点类似的一种比较排序。

该算法中,排序过程分两个阶段,奇交换和偶交换,两种交换都是成对出现。对于奇交换,它总是比较奇数索引以及其相邻的后续元素。对偶交换,总是比较偶数索引和其相邻的后续元素。思路是在数组中重复两趟扫描。第一趟扫描选择所有的数据项对,a[j]和a[j+1],j是奇数(j=1, 3, 5……)。如果它们的关键字的值次序颠倒,就交换它们。第二趟扫描对所有的偶数数据项进行同样的操作(j=2, 4,6……)。重复进行这样两趟的排序直到数组全部有序。

简单来说就是:奇数列排一趟序,偶数列排一趟序,再奇数排,再偶数排,直到全部有序。

动态图如下:

示例:

待排数组[6 2 4 1 5 9]   //目标按从小到大排序

第一次比较奇数列,奇数列与它的邻居偶数列比较,如6和2比,4和1比,5和9比

[6 2 4 1 5 9]

交换后变成

[2 6 1 4 5 9]

第二次比较偶数列,即6和1比,5和5比

[2 6 1 4 5 9]

交换后变成

[2 1 6 4 5 9]

第三次又是奇数列,选择的是2,6,5分别与它们的邻居列比较

[2 1 6 4 5 9]

交换后

[1 2 4 6 5 9]

第四次偶数列

[1 2 4 6 5 9]

一次交换

[1 2 4 5 6 9]

疑问:怎么就变成并行算法了?

从示例中,可看出整个比较交换分为独立的奇阶段或偶阶段。在每个阶段内,所有的比较和交换是没有数据相关性。因此,每一次比较和交换都可独立执行,也就可以并行化了。比如,第一次奇阶段排序中,100个元素可以分为4个CPU执行,第一个排序1-25,第二个排序26-50,第三个排序51-75,第四个排序76-100。

代码实现:

奇偶排序的串行实现

exchFlag记录当前迭代是否发生了数据交换,start变量表示是奇交换还是偶交换。

初始时:start为0,表示偶交换,每次迭代结束后,切花start的状态。如果上一次比较交换发生了数据交换,或当前正在进行的是奇交换,循环就不会停止,直到程序不会在发生交换,并且当前进行的是偶交换为止(表示奇偶交换已经成对出现)。

改造成并行模式,使用countDownLatch。

代码第9行,定义了奇偶排序的任务类,该任务的主要工作是进行数据比较和必要的交换(18-23行)。

并行排序的主体是pOddEvenSort()方法,使用CountDownLatch记录线程数量,对于每一次迭代,使用单独的线程对每一次元素比较和交换进行操作。在下一次迭代开始前,必须等待上一次迭代所有线程的完成。

时间: 2024-11-05 23:26:16

奇偶排序的相关文章

Openjudge-计算概论(A)-整数奇偶排序

描述: 输入10个整数,彼此以空格分隔重新排序以后输出(也按空格分隔),要求:1.先输出其中的奇数,并按从大到小排列:2.然后输出其中的偶数,并按从小到大排列.输入任意排序的10个整数(0-100),彼此以空格分隔输出按照要求排序后输出,由空格分隔样例输入 4 7 3 13 11 12 0 47 34 98 样例输出 47 13 11 7 3 0 4 12 34 98 提示1. 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>...>&g

题目1117:整数奇偶排序 (2008年北京大学图形实验室计算机研究生机试真题)

题目描述: 输入10个整数,彼此以空格分隔.重新排序以后输出(也按空格分隔),要求:1.先输出其中的奇数,并按从大到小排列:2.然后输出其中的偶数,并按从小到大排列. 输入: 任意排序的10个整数(0-100),彼此以空格分隔. 输出: 可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔. 样例输入: 4 7 3 13 11 12 0 47 34 98 样例输出: 47 13 11 7 3 0 4 12 34 98 提示: 1. 测试数据可能有很多组,请使用while(cin>>

华为机试—元素按奇偶排序

题目:元素按奇偶排序 给定一个数组input[],如果数组长度n为奇数,则将数组中最大的元素放到 output[]数组最中间的位置, 如果数组长度n为偶数,则将数组中最大的元素放到 output[]数组中间两个位置偏右的那个位置上, 然后再按从大到小的顺序,依次在最大元素放置的那个位置的两边,按照一左一右的顺序,依次存放剩下的数. 例如:input[] = {3, 6, 1, 9, 7}   output[] ={3, 7, 9, 6, 1};      input[] = {3, 6, 1,

经典算法题每日演练——第二十二题 奇偶排序

原文:经典算法题每日演练--第二十二题 奇偶排序 这个专题因为各种原因好久没有继续下去了,MM吧...你懂的,嘿嘿,不过还得继续写下去,好长时间不写,有些东西有点生疏了, 这篇就从简单一点的一个“奇偶排序”说起吧,不过这个排序还是蛮有意思的,严格来说复杂度是O(N2),不过在多核的情况下,可以做到 N2 /(m/2)的效率,这里的m就是待排序的个数,当m=100,复杂度为N2 /50,还行把,比冒泡要好点,因为重点是解决问题的奇思妙想. 下面我们看看这个算法是怎么描述的,既然是奇偶,肯定跟位数有

奇偶排序算法

奇偶排序,或奇偶换位排序,或砖排序,是一种相对简单的排序算法,最初发明用于有本地互连的并行计算.这是与冒泡排序特点类似的一种比较排序.该算法中,通过比较数组中相邻的(奇-偶)位置数字对,如果该奇偶对是错误的顺序(第一个大于第二个),则交换.下一步重复该操作,但针对所有的(偶-奇)位置数字对.如此交替进行下去. 使用奇偶排序法对一列随机数字进行排序的过程 本文地址:http://www.cnblogs.com/archimedes/p/odd-even-sort-algorithm.html,转载

排序算法系列:奇偶排序算法

概述 在上一篇中我们说到了冒泡排序的原理及实现详解.冒泡排序是一种交换排序,本文还是接着上一讲,说说另一种交换排序算法--奇偶排序. 版权说明 本文链接:http://blog.csdn.net/lemon_tree12138/article/details/50605563 – Coding-Naga - 转载请注明出处 目录 概述 版权说明 目录 奇偶排序算法 算法原理 算法原理图 算法步骤 算法可行性证明 算法过程图 算法实现 算法复杂度分析 Ref GitHub源码下载 奇偶排序算法 奇

C语言实现数组的奇偶排序

今天遇到了个实现数组的奇偶排序的问题,与大家分享下解决思路. 思路1:创建新的数组对所求数组进行遍历,技术放在一起偶数放在一起,再用穿件数组中的内容替换到所求数组中,代码如下: #define LEN 10 #include<stdio.h> #include<stdlib.h> int main() { int arr[LEN] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };//数组的初始化 int odd[LEN] = { 0 };//用来存储奇数 in

排序算法之奇偶排序 JAVA奇偶排序算法

奇偶排序法的思路是在数组中重复两趟扫描.第一趟扫描选择所有的数据项对,a[j]和a[j+1],j是奇数(j=1, 3, 5……).如果它们的关键字的值次序颠倒,就交换它们.第二趟扫描对所有的偶数数据项进行同样的操作(j=2, 4,6……).重复进行这样两趟的排序直到数组全部有序. public static void oddEvenSort(int[] arr){ int len = arr.length; int groupNumber = (int) Math.ceil((double)le

经典排序算法 - 奇偶排序Odd-even sort

经典排序算法 - 奇偶排序Odd-even sort 又一个比较性质的排序,基本思路是奇数列排一趟序,偶数列排一趟序,再奇数排,再偶数排,直到全部有序 举例吧, 待排数组[6 2 4 1 5 9] 第一次比较奇数列,奇数列与它的邻居偶数列比较,如6和2比,4和1比,5和9比 [6 2 4 1 5 9] 交换后变成 [2 6 1 4 5 9] 第二次比较偶数列,即6和1比,5和5比 [2 6 1 4 5 9] 交换后变成 [2 1 6 4 5 9] 第三趟又是奇数列,选择的是2,6,5分别与它们的