冒泡排序是非常基础的排序算法,本文我们看看在 Bash 脚本中如何写冒泡排序。本文的演示环境为 ubuntu 16.04。

冒泡排序的简要描述如下:

  • 通过连续的比较对数组中的元素进行排序
  • 比较两个相邻的元素,如果顺序不对,就交换这两个元素的位置
  • 当第一轮比较结束之后,最 "重" 的元素就会被移动到最底部
  • 当第二轮比较结束之后,第二 "重" 的元素就会被移动到次底部的位置
  • 这意味着每轮比较不需要比较之前已经 "沉淀" 好的数据
  • 如果有 n 个元素,则一共执行 n-1 轮比较

用 for 循环实现冒泡

准备一个数组(Bash 数组相关的内容请参考《Bash : 索引数组》一文):

declare -a myArr=(10 1 30 13 2 22)

然后来主备一个交换数组元素的函数:

# 定义函数 exchangeEle() 交换数组中两个元素的位置
exchangeEle()
{# 使用临时变量保存数组元素local temp=${myArr[$1]}# 交换元素的位置myArr[$1]=${myArr[$2]}myArr[$2]=$tempreturn
}

下面通过一个经典的两层循环来完成排序:

# 获取数组的长度
arrlen=${#myArr[@]}# 通过 for 循环对数组排序,注意此时是以字符串来比较的
for (( last = $arrlen ; last > 1 ; last-- ))
dofor (( i = 0 ; i < last - 1 ; i++ ))do[[ "${myArr[$i]}" > "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+1))done
done

这就 OK 了,跑跑看:

好吧,数字被作为字符串来比较了。修正这个问题非常简单,把比较的代码换成下面的就可以了:

[[ "${myArr[$i]}" -gt "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+1))

关于 Bash 中的比较操作,请参考《Bash : test 命令》一文。
再运行一次,就能看到正确结果了:

用 while 循序实现冒泡

下面我们来介绍使用 while 循序的版本。这次我们按字母序来排列数组中存放的国家名称:

myArr=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria \
Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England)

这里我们使用了转义符 \ 将数组元素的值放在不同的行上,这样可以避免行中的内容过长。具体的代码如下:

# 从索引 0 开始列出整个数
echo "The order of the original data in the array:"
echo "${myArr[*]}"# 获取数组的长度,并用来控制循环的次数。
n=${#myArr[@]}echo "Start bubbling sort:"
while [ "$n" -gt 1 ] # 执行 n-1 轮外部循环。
doindex=0 # 内部循环时的数组元素索引,在每轮循环开始之前需要重置。while [ "$index" -lt $(expr $n - 1) ] # 开始内部循环。doif [[ ${myArr[$index]} > ${myArr[$(expr $index + 1)]} ]]thenexchangeEle $index $(expr $index + 1) # 交换数组元素位置。filet "index += 1"done # 内部循环结束。let "n -= 1" # 外部循环计数减 1。# 输出每轮排序后的结果。echo "${myArr[*]}"
done # 外部循环结束。echo "Sorted data order:"
echo "${myArr[*]}"

同样是两层循环,算法完全一样,只不过是写法有一点点不同。为了显示排序的过程,这次输出了每轮排序后的中间结果:

demo 代码

下面是本文中 demo 的完整代码:

#!/bin/bash
# bubble.sh, 本例主要用来演示索引数组的排序
# 冒泡排序的简要描述如下:
# 通过连续的比较对数组中的元素进行排序
# 比较两个相邻的元素,如果顺序不对,就交换这两个元素的位置
# 当第一轮比较结束之后,最 "重" 的元素就会被移动到最底部
# 当第二轮比较结束之后,第二 "重" 的元素就会被移动到次底部的位置
# 这意味着每轮比较不需要比较之前已经 "沉淀" 好的数据
# 一共执行 n-1 轮比较# 定义函数 exchangeEle() 交换数组中两个元素的位置
exchangeEle()
{# 使用临时变量保存数组元素local temp=${myArr[$1]}# 交换元素的位置myArr[$1]=${myArr[$2]}myArr[$2]=$tempreturn
}declare -a myArr=(10 1 30 13 2 22)# 从索引 0 开始列出整个数组
echo "The order of the original data in the array:"
echo "${myArr[*]}"# 获取数组的长度
arrlen=${#myArr[@]}# 通过 for 循环对数组排序,注意此时是以字符串来比较的
for (( last = $arrlen ; last > 1 ; last-- ))
dofor (( i = 0 ; i < last - 1 ; i++ ))do[[ "${myArr[$i]}" > "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+1))done
doneecho "Sorted data order as string:"
echo "${myArr[*]}"# 通过 for 循环对数组排序,这次是作为整数来比较
for (( last = $arrlen ; last > 1 ; last-- ))
dofor (( i = 0 ; i < last - 1 ; i++ ))do[[ "${myArr[$i]}" -gt "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+1))done
doneecho "Sorted data order as number:"
echo "${myArr[*]}"myArr=(Ukraine Zaire Russia Yemen Syria \
Argentina Japan Mexico Greece)
#这里我们还使用转义符 \ 将数组元素的值放在不同的行上,这样可以避免行中的内容过长。# 从索引 0 开始列出整个数
echo "The order of the original data in the array:"
echo "${myArr[*]}"# 获取数组的长度,并用来控制循环的次数。
n=${#myArr[@]}echo "Start bubbling sort:"
while [ "$n" -gt 1 ] # 执行 n-1 轮外部循环。
doindex=0 # 内部循环时的数组元素索引,在每轮循环开始之前需要重置。while [ "$index" -lt $(expr $n - 1) ] # 开始内部循环。doif [[ ${myArr[$index]} > ${myArr[$(expr $index + 1)]} ]]thenexchangeEle $index $(expr $index + 1) # 交换数组元素位置。filet "index += 1"done # 内部循环结束。let "n -= 1" # 外部循环计数减 1。# 输出每轮排序后的结果。echo "${myArr[*]}"
done # 外部循环结束。echo "Sorted data order:"
echo "${myArr[*]}"

参考:
《高级 Bash 脚本编程指南》

转载于:https://www.cnblogs.com/sparkdev/p/10345498.html

Bash : 冒泡排序相关推荐

  1. Shell各种排序方式

    目录 冒泡排序 插入排序 直接选择排序 反转排序 冒泡排序 冒泡排序,该排序的命名非常形象,即一个个将气泡冒出.冒泡排序一趟冒出一个最大(或最小)值. #!/bin/bash #冒泡排序,升序 arr ...

  2. acm之简单博弈 Nim Bash Wythoff

    前些日子我打算开了博弈基础,事后想进行总结下 一句话就是分析必胜或必败,异或为0. 以下内容来自转载: Nim游戏的概述: 还记得这个游戏吗? 给出n列珍珠,两人轮流取珍珠,每次在某一列中取至少1颗珍 ...

  3. shell函数与数组(了解函数,递归函数运用,了解数组,创建基数和偶数数组,冒泡排序,调试命令)

    文章目录 shell函数 了解函数 函数定义 递归函数 举例子 shell数组 定义数组 数组包括的数据类型与数组操作 数组操作 举例(快速创建数组.奇数数组) 冒泡排序法 调试命令 set命令 ba ...

  4. python-Day5-深入正则表达式--冒泡排序-时间复杂度 --常用模块学习:自定义模块--random模块:随机验证码--time datetime模块...

    正则表达式 语法: mport re #导入模块名 p= re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0-9]代表匹配0至9的任意一个 ...

  5. shell脚本之数组,冒泡排序算法

    目录 一.数组 1.定义数组 2. 数组中数据类型 2.1数值类型 2.2字符类型 二.数组的用法 1. 输出数组中的值 2. 统计数组参数个数 ​编辑 3.查看数组下标列表 4.分割字符串 5.替换 ...

  6. linux程序包管理rpm,yum和编译安装以及冒泡排序练习

    linux程序包管理: API:Application Programming Interface POSIX:Portable OS 程序源代码--> 预处理--> 编译--> 汇 ...

  7. shell运用——冒泡排序

    冒泡排序 类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断的向前移动 基本思想: 冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素 ...

  8. 11、bash编程之数组

    bash编程: 数组初步 数组:数据结构, 数组是一个序列(当我需要连续存储大量数据时) 声明数组:declare -a arrayName(数组也是可以直接拿来用,也可以不需要定义) 初始化或赋值: ...

  9. Linux随笔10-Ubuntu网络配置、非交互式远程主机登录以及shell中的数组应用(冒泡排序数组中的元素)

    Contents 1. Ubuntu系统网络配置总结 1.1. 配置主机名 1.2. 配置网卡名称 1.3. 配置网卡IP地址 2. 非交互式远程主机登录 2.1. 使用expect实现 2.2. 使 ...

  10. pip 升级之后提示 bash: /usr/bin/pip3: No such file or directory

    1. 问题现象 pip 升级之后使用时报错: $ pip3 -V bash: /usr/bin/pip3: No such file or directory 通过命令查找 pip 位置 $ whic ...

最新文章

  1. 使用MapReduce程序完成相关数据预处理(二)
  2. 【目标检测系列】CNN中的目标多尺度处理方法
  3. 【Win 10 应用开发】将墨迹保存到图像的两种方法
  4. 求一个简单的java线程代码,Java线程代码的实现方法
  5. ue4 rpc php,UE4 RPC在C++中的使用简例
  6. 微信小程序实现无限滚动列表
  7. 快头条月增迅猛超微视 三四线城市“流量炼金”的上限在哪?
  8. Machinations——可视化游戏设计
  9. mysql定期删除数据_mysql数据库如何实现定期删除数据库一些东西
  10. Openfire3.9.3源代码导入eclipse中开发配置指南(转载)
  11. python3.x和python2.x唯一区别_Python3.x和Python2.x的区别 (转)
  12. .net core webapi 文件上传在 Swagger 文档中的有好提示处理
  13. 深入理解多线程(四)—— Moniter的实现原理
  14. 物体长度测量---------C#+Emgucv
  15. PWM的周期和占空比是如何计算
  16. 多开分身苹果版_【苹果/安卓】影分身,我们每个人都会!
  17. 华为openGauss初级OGCA认证100%通过
  18. Docker 安装和部署
  19. 操作系统——(11)多媒体操作系统
  20. 【计息日期】国债逆回购类产品的起息日期和兑付日期,如何用python优雅实现?~

热门文章

  1. JCheckBox 默认选择_了解GoldWave使用习惯的一些默认设置
  2. 剖析HotSpot的初始化过程
  3. [渝粤教育] 龙岩学院 Web信息系统应用开发 参考 资料
  4. 【渝粤教育】国家开放大学2018年秋季 0179-21T数据库基础与应用 参考试题
  5. 建筑系学生怎么系统地学 Photoshop、CAD 之类软件?
  6. UI_DEV_Environment 之 StoryBook
  7. SQL SERVER如何通过SQL语句获服务器硬件和系统信息
  8. 使数据可供ArcGIS Server访问
  9. MongoDB,子查询
  10. [转] 各种数据类型转换