对于排序算法相信大家都不陌生,大部分排序的程序都是串行的排序算法,比如冒泡排序,插入排序,选择排序,堆排序等等,但是随着计算机的发展,现在的计算机都是多核的处理器,串行排序无法高效的利用CPU,为了更加有效的利用CPU,我们在这里介绍一下在并行世界中的排序算法。

一、奇偶交换排序

在介绍并行排序之前,我们有必要介绍一下奇偶排序,为了将串行排序算法改为并行排序,使用奇偶排序可以更加方便的修改程序为并行排序。

1.什么是奇偶交换排序?
奇偶排序分为两个阶段,奇交换和偶交换。奇交换就是将比较数组奇数索引以及与其相邻的之后的元素,偶交换就是比较数组偶数索引和其相邻的后续元素,并且,奇交换和偶交换总是成对出现,这样才能保证涉及到数组中的每一个元素。

这里我们举一个例子,图解一下奇偶交换排序,假如这里我们对5,45,6,3,4 这五个数进行排序,下面我们来看看它具体是怎么进行奇偶交换的。(图画的有点丑哈_

通过上面的图解我们可以很清除的明白奇偶交换排序的原理。下面我们来写一下串行的奇偶交换排序的代码:

package cn.just.thread.concurrent;
/*** 奇偶排序* @author Shinelon**/
public class OddEventSort {public static void sort(int[] arr){int exchange=1,start=0,temp;    //exchange记录当前循环是否进行了数据交换while(exchange==1||start==1){  //start==1保证奇偶排序成对出现exchange=0;      //没有发生交换for(int i=start;i<arr.length-1;i+=2){ //刚开始进行偶排序if(arr[i]>arr[i+1]){temp=arr[i];arr[i]=arr[i+1];arr[i+1]=temp;exchange=1;}}if(start==0)start=1;elsestart=0;}}public static void main(String[] args) {int[] a={12,25,45,78,69,45,58,26,78,49,12,2,23,5,89,45,78,58,20,19};sort(a);for(int i=0;i<a.length;i++){System.out.println(a[i]);}}
}

二、并行排序
下面我们开始今天的正题,现在我们就开始将上面的串行的排序方式修改为并行排序,此时我们已经很清楚的认识了奇偶交换排序,【它总是和奇索引或者偶索引对应的数据之后的数进行比较并且交换,这样就不会出现一个数既可以和它之前的数进行交换,也可以和它之后的数进行交换,从而在并行的模式下多个线程之间不会相互干扰,这是使用奇偶交换排序来进行并行排序的关键所在。】
那么我们将怎么去分配线程的数量呢?并行的过程是怎么样的呢?我们还是以上面的数据为例进行讲解,在第一次偶交换的时候我们可以开启两个线程来分别交换5,45和6,3。同理,我们在接下来的奇交换时也开启两个线程来比较交换45,3和6,4。这样两个线程之间没有任务干扰,也不互相依赖,这样我们就正确的进行了并行排序。对于每次交换开启的线程数,我们可以通过以下方式来计算得到:

threadNumber=arr.length/2-(arr.length%2==0?start:0);

下面我们来写出完整的并行排序的程序:

package cn.just.thread.concurrent;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** 并行排序* @author Shinelon**/
public class CurrOddEventSort {public static int exchange=1;public static int[] arr={12,25,45,78,69,45,58,26,78,49,12,2,23,5,89,45,78,58,20,19};public static  int getExchange() {return exchange;}public static synchronized void setExchange(int exchange) {CurrOddEventSort.exchange = exchange;}public static class OddEventSortTask implements Runnable{int i;CountDownLatch latch;public OddEventSortTask(int i, CountDownLatch latch) {super();this.i = i;this.latch = latch;}public void sort(int[] arr){int temp;if(arr[i]>arr[i+1]){temp=arr[i];arr[i]=arr[i+1];arr[i+1]=temp;setExchange(1);}latch.countDown();}@Overridepublic void run() {sort(arr);}}public static void OddEventSort(int[] arr) throws InterruptedException {ExecutorService pool=Executors.newCachedThreadPool();int start=0;while(getExchange()==1||start==1){setExchange(0);//偶数的数组长度,当start为1时,只有length/2-1个线程CountDownLatch l=new CountDownLatch(arr.length/2-(arr.length%2==0?start:0));for(int i=start;i<arr.length-1;i+=2)pool.submit(new OddEventSortTask(i, l));//等待所有线程结束l.await();if(start==1)start=0;elsestart=1;}}public static void main(String[] args) throws InterruptedException {OddEventSort(arr);for(int i=0;i<arr.length;i++){System.out.println(arr[i]);}}
}

上面的代码不是很难读懂,有的人可能不了解CountDownLatch ,这里我们简单介绍一下CountDownLatch ,它是多线程控制的一个工具类,是一个倒计时器,构造函数 new CountDownLatch(int number)中的参数number是开启的计时器数目,CountDownLatch.await()方法要求主线程等待所有线程池中所有任务都执行完。CountDownLatch.countDown()是当一个任务执行完后数目减去1。


这里我们已经介绍完并行排序,在数据少的时候也许体现不出并行排序的优势,所以我们会选择串行排序,但是现在是大数据时代,当数据剧增时,并行排序就很有优势,效率很高,现在有很多大数据框架就是并行计算来处理海量数据的,感兴趣的小伙伴可以自己去了解,我们就介绍到这里(其实是比较菜,说不清楚,O(∩_∩)O哈哈~)。

如果你想和我们一起学习探讨,可以扫码加群:

不一样的排序算法【并行排序】相关推荐

  1. 排序算法---选择排序(java版)

    简单选择排序 原理 选择排序(Selection Sort)的原理有点类似插入排序,也分已排序区间和未排序区间.但是选择排序每次会从排序区间中找到最小的元素,将其放到已排序区间的末尾. 简单选择排序执 ...

  2. JavaScript实现十种经典排序算法(js排序算法)

    冒泡排序算法 冒泡排序(Bubble Sort)是一种简单直观的排序算法.冒泡排序算法的步骤描述如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一 ...

  3. C语言基础排序算法-选择排序

    C语言基础排序算法-选择排序 什么是选择排序? 选择排序(Selection sort)是一种简单直观的排序算法,第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从 ...

  4. C语言排序算法 选择排序 插入排序 快速排序 qsort实现快排 堆排序

    常见排序算法 选择排序 选择排序(Selection sort)是一种简单直观的排序算法. 它的工作原理如下. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素 ...

  5. 经典排序算法 - 鸡尾酒排序Cocktail sort

    经典排序算法 - 鸡尾酒排序Cocktail sort 鸡尾酒排序基于冒泡排序,双向循环 还是看例子吧,给定待排数组[2 3 4 5 1] 第一趟过去时的每一步 第一步迭代,2 < 3不换 [2 ...

  6. 经典排序算法 - 希尔排序Shell sort

    经典排序算法 - 希尔排序Shell sort 希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第 ...

  7. 经典排序算法 - 耐心排序Patience Sorting

    经典排序算法 - 耐心排序Patience Sorting 这个排序的关键在建桶和入桶规则上 建桶规则:如果没有桶,新建一个桶;如果不符合入桶规则那么新建一个桶 入桶规则:只要比桶里最上边的数字小即可 ...

  8. Java排序算法——选择排序

    Java排序算法--选择排序(Selection sort) 传送门 冒泡排序 插入排序 简述 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找 ...

  9. 三种线性排序算法 计数排序、桶排序与基数排序—— 转自:BYVoid

    三种线性排序算法 计数排序.桶排序与基数排序 [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种, ...

  10. python排序算法——希尔排序(附代码)

    python排序算法--希尔排序 文章目录 python排序算法--希尔排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序算法 ...

最新文章

  1. Java多线程系列七——ExecutorService
  2. vue点击网页全屏_vue-cli点击实现全屏功能(两种方式)
  3. 让 CPU 告诉你硬盘和网络到底有多慢
  4. 第一个QGLViewer程序
  5. 『数学』--数论--组合数+卢卡斯定理+扩展卢卡斯定理
  6. Python 进程 Process 模块 - Python零基础入门教程
  7. 四剑客查找字符_Shell四剑客Grep
  8. winform布局、控件
  9. python办公自动化(入门)
  10. 数据库开发常见面试题
  11. Android安卓原生实现微信登陆
  12. APS系统的实施步骤,外行人都能看懂
  13. Linux基础 之 curl 命令
  14. 采样频率和带宽的关系_ADI公司AD7380系列SAR ADC的片内过采样 - 模拟技术
  15. 蓝桥杯之未名湖边的烦恼-递归极简版(c++实现)
  16. Unity Shader——Shader实现大海的波涛效果
  17. open-falcon 修改配置文件
  18. vue-cil 浏览器控制台报错:this._init is not a function
  19. 真实环绕的魅力,飞利浦杜比全景声影院B8967开箱
  20. VOGUE: Secure User Voice Authentication on Wearable Devices using Gyroscope

热门文章

  1. 【AI绘画】——Midjourney关键词格式解析(常用参数分享)
  2. elementui 和vantUi表单validate区别
  3. 如何通过Win10系统的密码重置盘来重置电脑开机锁屏密码?
  4. C++ debug和release版本运行结果不一致浅析
  5. matlab产生伪随机序列,伪随机序列发生器PRBS7的matlab实现
  6. android uevent原理
  7. “打农药”都不省心:勒索病毒冒充王者荣耀外挂
  8. Light oj 1004 - Monkey Banana Problem(DP)
  9. TomCat卸载之后重新装另一个版本的TomCat安装程序的进度条安装到三分之一显示安装失败!!!!!!!!
  10. 基于TM的遥感数据的叶面积指数估算解决方案