目录

一、排序算法的分类

二、冒泡排序

1.原始的冒泡排序

2.改进一步的冒泡排序

3.更进一步的冒泡排序

三、鸡尾酒排序

四、完整测试代码


一、排序算法的分类

在介绍排序算法之前,我们先根据时间复杂度,罗列主流的排序算法,作为一个了解。大致分为以下三类:

1.时间复杂度为O(n^2)的排序算法

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 希尔排序(希尔排序比较特殊,性能略胜于O(n^2),但比不上O(nlogn))

2.时间复杂度为O(nlogn)的排序算法

  • 快速排序
  • 归并排序
  • 堆排序

3.时间复杂度为线性的排序算法

  • 计数排序
  • 桶排序
  • 基数排序

排序算法根据稳定性,又可分为稳定排序和不稳定排序。稳定排序是值相同的元素在排序后仍然保持着排序前的顺序,不稳定排序则是相反。

二、冒泡排序

思想:相邻元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置(右侧为最大元素位置);小于等于右侧元素时,位置不变(由此可见冒泡排序是稳定排序)。

冒泡排序每一轮都要比较剩余的所有元素,总共遍历n-1轮(最后还剩一个元素时不用比较),时间复杂度为O(n^2)。

1.原始的冒泡排序

最原始的冒泡排序通过上述的描述,我们可以用双层循环来实现,第一层循环控制遍历的次数,第二层循环进行两两比较。代码实现非常简单,如下所示。

    /*原始冒泡排序前后两个元素进行比较,大的元素往后移冒泡排序是稳定的排序*/public static void sort(int[] array){int temp;for(int j = 0; j < array.length - 1; j++)//控制进行几轮比较for(int i = 0; i < array.length-1-j; i++){//控制每一轮的比较if(array[i] > array[i+1]){temp = array[i+1];array[i+1] = array[i];array[i] = temp;}}}

2.改进一步的冒泡排序

若我们在某一轮比较之后,序列已经是有序的,那么就不用继续进行排序。基于此思想,我们设置一个布尔值(isSorted),在每一轮遍历之前将其设为true,若某轮比较发生了元素的交换,则将该值设置为false。最后在未发生交换元素的那轮,该值为true,我们可以跳出循环,得到的便是排好序的序列。

    /*冒泡排序第二版改进(一轮有序后不必再排序)当有一轮排序后若已经有序,则剩下的几轮排序就不必执行了*/public static void sort1(int[] array){int temp;boolean isSorted;for(int j = 0; j < array.length - 1; j++)//控制进行几轮比较{isSorted = true;//用isSorted假设每次序列都是有序的for(int i = 0; i < array.length-1-j; i++){//控制每一轮的比较if(array[i] > array[i+1]){temp = array[i+1];array[i+1] = array[i];array[i] = temp;isSorted = false;//若有元素交换,则是无序的还需进行下一趟遍历}}if(isSorted)break;}}

3.更进一步的冒泡排序

适用于序列中部分序列已经为有序的情况(如:3,4,2,1,5,6,7,8,前半部分无序,后半部分有序),我们无需每轮都比较它们,因此可以设置一个无序的边界值,记录交换的元素的位置。(个人觉得该方法不是非常实用(但书本上是这样介绍的),效果其实和在一次交换元素后就跳出内层循环一样)

    /*冒泡排序第三版改进(记录最后一次元素交换的位置,该位置为无序边界区)该方法相当于交换一次之后就退出当前循环,可以减少交换次数*/public static void sort2(int[] array){for(int j = 0; j < array.length-1; j++)//控制进行几轮比较{boolean isSorted = true;//用isSorted假设每次序列都是有序的int sortBorder = array.length - 1;for(int i = 0; i < sortBorder; i++){//控制每一轮的比较int temp = 0;if(array[i] > array[i+1]){temp = array[i+1];array[i+1] = array[i];array[i] = temp;isSorted = false;//若有元素交换,则是无序的还需进行下一趟遍历sortBorder = i;//把无序数列的边界更新为最后一次交换元素的位置}}if(isSorted)break;}}

三、鸡尾酒排序

首先声明,鸡尾酒排序从本质上来说也是冒泡排序。

鸡尾酒排序和原始的冒泡排序的区别是,该排序的比较和交换元素的顺序是双向的(即第一轮从左到右两两比较比较,第二轮从右到左比较,第三轮又从左到右比较......)。

如,我们给出要排序的序列为{2,3,4,5,6,7,8,1},若按照正常的冒泡排序,则每次排序都需要从左到右比较,将最后一个1放到最前面需要进行7轮比较,但若我们采用上面鸡尾酒排序的思想,则只需进行3轮排序:第一轮从左到右排序为{2,3,4,5,6,7,1,8},第二轮从右到左排序为{1,2,3,4,5,6,7,8},在两轮之后其实已经有序,但我们还要再进行一轮判断。因此总共只需3次即可,大大减少了比较次数。

鸡尾酒排序中,我们用外循环中套两个小循环(分别为奇数次和偶数次)来实现。

    //鸡尾酒排序,从左到右比较和从右到左比较轮流进行,适用于部分有序的情况如2,3,4,5,6,7,8,1public static void sort3(int[] array){int temp = 0;for(int i = 0; i < array.length/2; i++){boolean isSorted = true;//奇数轮,从左到右比较和交换for(int j = i; j < array.length - i - 1; j++){if(array[j] > array[j+1]){temp = array[j];array[j] = array[j+1];array[j+1] = temp;isSorted = false;}}if(isSorted)break;isSorted = true;//偶数轮,从右到左比较和交换for(int j = array.length-i-1; j > i; j--){if(array[j] < array[j-1]){temp = array[j];array[j] = array[j-1];array[j-1] = temp;isSorted = false;}}if(isSorted)break;}}

四、完整测试代码

import java.util.Arrays;public class MySort {/*原始冒泡排序前后两个元素进行比较,大的元素往后移冒泡排序是稳定的排序*/public static void sort(int[] array){int temp;for(int j = 0; j < array.length - 1; j++)//控制进行几轮比较for(int i = 0; i < array.length-1-j; i++){//控制每一轮的比较if(array[i] > array[i+1]){temp = array[i+1];array[i+1] = array[i];array[i] = temp;}}}/*冒泡排序第二版改进(一轮有序后不必再排序)当有一轮排序后若已经有序,则剩下的几轮排序就不必执行了*/public static void sort1(int[] array){int temp;boolean isSorted;for(int j = 0; j < array.length - 1; j++)//控制进行几轮比较{isSorted = true;//用isSorted假设每次序列都是有序的for(int i = 0; i < array.length-1-j; i++){//控制每一轮的比较if(array[i] > array[i+1]){temp = array[i+1];array[i+1] = array[i];array[i] = temp;isSorted = false;//若有元素交换,则是无序的还需进行下一趟遍历}}if(isSorted)break;}}/*冒泡排序第三版改进(记录最后一次元素交换的位置,该位置为无序边界区)该方法相当于交换一次之后就退出当前循环,可以减少交换次数*/public static void sort2(int[] array){for(int j = 0; j < array.length-1; j++)//控制进行几轮比较{boolean isSorted = true;//用isSorted假设每次序列都是有序的int sortBorder = array.length - 1;for(int i = 0; i < sortBorder; i++){//控制每一轮的比较int temp = 0;if(array[i] > array[i+1]){temp = array[i+1];array[i+1] = array[i];array[i] = temp;isSorted = false;//若有元素交换,则是无序的还需进行下一趟遍历sortBorder = i;//把无序数列的边界更新为最后一次交换元素的位置}}if(isSorted)break;}}//鸡尾酒排序,从左到右比较和从右到左比较轮流进行,适用于部分有序的情况如2,3,4,5,6,7,8,1public static void sort3(int[] array){int temp = 0;for(int i = 0; i < array.length/2; i++){boolean isSorted = true;//奇数轮,从左到右比较和交换for(int j = i; j < array.length - i - 1; j++){if(array[j] > array[j+1]){temp = array[j];array[j] = array[j+1];array[j+1] = temp;isSorted = false;}}if(isSorted)break;isSorted = true;//偶数轮,从右到左比较和交换for(int j = array.length-i-1; j > i; j--){if(array[j] < array[j-1]){temp = array[j];array[j] = array[j-1];array[j-1] = temp;isSorted = false;}}if(isSorted)break;}}public static void main(String[] args) {int[] array = new int[]{5,8,6,3,9,2,1,7};sort1(array);System.out.println(Arrays.toString(array));int[] array1 = new int[]{3,4,2,1,5,6,7,8};sort2(array1);System.out.println(Arrays.toString(array1));int[] array2 = new int[]{2,3,4,5,6,7,8,1};sort3(array2);System.out.println(Arrays.toString(array2));}
}

排序算法之冒泡排序及鸡尾酒排序相关推荐

  1. 十大排序算法:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

    冒泡排序.选择排序.插入排序.希尔排序.归并排序.快速排序.堆排序.计数排序.桶排序.基数排序的动图与源代码. 目录 关于时间复杂度 冒泡排序 选择排序 插入排序 希尔排序 归并排序 快速排序 堆排序 ...

  2. 基础排序算法(冒泡排序,选择排序,插入排序)

    最近经常调用api中的排序算法,很少自己写了,有时候也只写写快速排序这些比较快的排序,然而刚开始学排序时用的一些基本的排序算法却有点忘了 正好今天Java老师让我们每个人写个选择排序热热手,趁这个机会 ...

  3. python遍历数组冒泡排序_经典排序算法(冒泡排序,选择排序,插入排序,快速排序,堆排序)python实现...

    最近在复习经典排序算法,自己用python也实现了一下,这里不会涉及到原理(因为网上方法已经很详细啦),就把函数贴上来,可以让大家自己试着运行下,再结合别处的原理也可以更好地理解它们的实现. 如果有错 ...

  4. java冒泡排序_JAVA实现经典排序算法(冒泡排序、选择排序、插入排序、希尔排序、堆排序、归并排序、快速排序)...

    冒泡排序 依次比较相邻的元素,若发现逆顺序,则交换.小的向前换,大的向后换,本次循环完毕之后再次从头开始扫描,直到某次扫描中没有元素交换,说明每个元素都不比它后面的元素大,至此排序完成. import ...

  5. 【完整可运行源码+GIF动画演示】十大经典排序算法系列——冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

    以前也零零碎碎发过一些排序算法,但总是不系统, 这次彻底的对排序系列做了一个整体的规划, 小伙伴们快快mark哦~ [GIF动画+完整可运行源代码]C++实现 冒泡排序--十大经典排序算法之一 [GI ...

  6. Python排序算法(一)冒泡排序、选择排序、插入排序

    今天总结一下Python中的排序算法.这篇文章有的排序算法是:冒泡排序.选择排序.插入排序. 冒泡排序 先看一下代码. ''' 冒泡排序 '''def bubble_sort(aList):n = l ...

  7. 排序算法(冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序)

    排序也叫排序算法,排序是将一组数据,依指定的顺序进行排列的过程. 排序的分类: 1)内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序. 2)外部排序:数据量过大,无法全部加载到内存中,需要 ...

  8. 浅谈排序算法:冒泡排序法和选择排序法的区别

    之前学习了冒泡排序法和选择排序法,最近被老师问某个道题用的是什么排序法.自己居然答不出来,才发现自己没有真正弄懂,这两个算法的原理和区别,所以····· 1冒泡排序法 1.1什么是冒泡排序法? 顾名思 ...

  9. C语言实例——四种排序算法(冒泡排序、选择排序、插入排序、快速排序)

    C 语言排序算法 BB Time 一.冒泡排序 1.原理 2.代码 二.选择排序 1.原理 2.代码 三.插入排序 1.原理 2.代码 四.快速排序 1.原理 2.代码 3.操作过程 BB Again ...

最新文章

  1. github下载慢,轻松提速教程
  2. java多线程之wait和notify
  3. php如何取消bak自动备份_教你如何进行异地自动备份数据库
  4. Android下添加新的自定义键值和按键处理流程【转】
  5. sublimeformaya
  6. python学什么版本2020年_2020年了居然还有人在学Python?学python有什么用?
  7. 环境变量bootcmd、bootargs的参数含义
  8. flowable 数据库表结构 梳理
  9. 过滤器-filter
  10. 【UOJ #351】新年的叶子(树的直径,期望)
  11. 闲暇时间做的一个亲属关系计算器
  12. 【C】狐狸找兔子问题
  13. 示波器X-Y模式显示利萨如(李沙育)与DIY图像
  14. scuctf赛后自闭
  15. 蓝桥杯2017国赛 瓷砖样式 dfs+map
  16. python数据统计分析
  17. 金庸笔下用脚发暗器_移动的艺术:使用明暗器图创建动画材质
  18. c语言编程a4988驱动步进电机,A4988 步进电机驱动模块测试
  19. RT-Thread物联网操作系统介绍:10、计数信号量
  20. html加拼音注释,HTML——格式化文本标记、拼音/音标注释ruby 标记和rt/rp 标记、段落缩进标记blockquote、预格式化标记pre...

热门文章

  1. 十进制与二进制转化计算
  2. Bluetooth 蓝牙介绍(一) :基础知识
  3. 盘点国内外那些API调试工具
  4. iOS-获取当前View所在的控制器
  5. 腾讯云8核16G服务器18M带宽CPU性能可支撑多少人同时在线?
  6. 关于AI视觉-如何连接使用智能语音开发套件(USB语音开发套件)
  7. i12 tws无线蓝牙耳机说明书
  8. android 好友字母分组,Android好友联系人按字母排序分组,自定义通讯录导航栏View...
  9. php表单页面防重复提交方法总结
  10. Element 对象的使用