Bash : 冒泡排序
冒泡排序是非常基础的排序算法,本文我们看看在 Bash 脚本中如何写冒泡排序。本文的演示环境为 ubuntu 16.04。
冒泡排序的简要描述如下:
- 通过连续的比较对数组中的元素进行排序
- 比较两个相邻的元素,如果顺序不对,就交换这两个元素的位置
- 当第一轮比较结束之后,最 "重" 的元素就会被移动到最底部
- 当第二轮比较结束之后,第二 "重" 的元素就会被移动到次底部的位置
- 这意味着每轮比较不需要比较之前已经 "沉淀" 好的数据
- 如果有 n 个元素,则一共执行 n-1 轮比较
用 for 循环实现冒泡
准备一个数组(Bash 数组相关的内容请参考《Bash : 索引数组》一文):
declare -a myArr=( )
然后来主备一个交换数组元素的函数:
# 定义函数 exchangeEle() 交换数组中两个元素的位置
exchangeEle()
{
# 使用临时变量保存数组元素
local temp=${myArr[$]}
# 交换元素的位置
myArr[$]=${myArr[$]}
myArr[$]=$temp return
}
下面通过一个经典的两层循环来完成排序:
# 获取数组的长度
arrlen=${#myArr[@]} # 通过 for 循环对数组排序,注意此时是以字符串来比较的
for (( last = $arrlen ; last > ; last-- ))
do
for (( i = ; i < last - ; i++ ))
do
[[ "${myArr[$i]}" > "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+))
done
done
这就 OK 了,跑跑看:

好吧,数字被作为字符串来比较了。修正这个问题非常简单,把比较的代码换成下面的就可以了:
[[ "${myArr[$i]}" -gt "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+))
关于 Bash 中的比较操作,请参考《Bash : test 命令》一文。
再运行一次,就能看到正确结果了:

用 while 循序实现冒泡
下面我们来介绍使用 while 循序的版本。这次我们按字母序来排列数组中存放的国家名称:
myArr=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria \
Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England)
这里我们使用了转义符 \ 将数组元素的值放在不同的行上,这样可以避免行中的内容过长。具体的代码如下:
# 从索引 开始列出整个数
echo "The order of the original data in the array:"
echo "${myArr[*]}" # 获取数组的长度,并用来控制循环的次数。
n=${#myArr[@]} echo "Start bubbling sort:"
while [ "$n" -gt ] # 执行 n- 轮外部循环。
do
index= # 内部循环时的数组元素索引,在每轮循环开始之前需要重置。
while [ "$index" -lt $(expr $n - ) ] # 开始内部循环。
do
if [[ ${myArr[$index]} > ${myArr[$(expr $index + )]} ]]
then
exchangeEle $index $(expr $index + ) # 交换数组元素位置。
fi
let "index += 1"
done # 内部循环结束。
let "n -= 1" # 外部循环计数减 。
# 输出每轮排序后的结果。
echo "${myArr[*]}"
done # 外部循环结束。 echo "Sorted data order:"
echo "${myArr[*]}"
同样是两层循环,算法完全一样,只不过是写法有一点点不同。为了显示排序的过程,这次输出了每轮排序后的中间结果:

demo 代码
下面是本文中 demo 的完整代码:
#!/bin/bash
# bubble.sh, 本例主要用来演示索引数组的排序
# 冒泡排序的简要描述如下:
# 通过连续的比较对数组中的元素进行排序
# 比较两个相邻的元素,如果顺序不对,就交换这两个元素的位置
# 当第一轮比较结束之后,最 "重" 的元素就会被移动到最底部
# 当第二轮比较结束之后,第二 "重" 的元素就会被移动到次底部的位置
# 这意味着每轮比较不需要比较之前已经 "沉淀" 好的数据
# 一共执行 n- 轮比较 # 定义函数 exchangeEle() 交换数组中两个元素的位置
exchangeEle()
{
# 使用临时变量保存数组元素
local temp=${myArr[$]}
# 交换元素的位置
myArr[$]=${myArr[$]}
myArr[$]=$temp return
} declare -a myArr=( ) # 从索引 开始列出整个数组
echo "The order of the original data in the array:"
echo "${myArr[*]}" # 获取数组的长度
arrlen=${#myArr[@]} # 通过 for 循环对数组排序,注意此时是以字符串来比较的
for (( last = $arrlen ; last > ; last-- ))
do
for (( i = ; i < last - ; i++ ))
do
[[ "${myArr[$i]}" > "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+))
done
done echo "Sorted data order as string:"
echo "${myArr[*]}" # 通过 for 循环对数组排序,这次是作为整数来比较
for (( last = $arrlen ; last > ; last-- ))
do
for (( i = ; i < last - ; i++ ))
do
[[ "${myArr[$i]}" -gt "${myArr[$((i+1))]}" ]] && exchangeEle $i $((i+))
done
done echo "Sorted data order as number:"
echo "${myArr[*]}" myArr=(Ukraine Zaire Russia Yemen Syria \
Argentina Japan Mexico Greece)
#这里我们还使用转义符 \ 将数组元素的值放在不同的行上,这样可以避免行中的内容过长。 # 从索引 开始列出整个数
echo "The order of the original data in the array:"
echo "${myArr[*]}" # 获取数组的长度,并用来控制循环的次数。
n=${#myArr[@]} echo "Start bubbling sort:"
while [ "$n" -gt ] # 执行 n- 轮外部循环。
do
index= # 内部循环时的数组元素索引,在每轮循环开始之前需要重置。
while [ "$index" -lt $(expr $n - ) ] # 开始内部循环。
do
if [[ ${myArr[$index]} > ${myArr[$(expr $index + )]} ]]
then
exchangeEle $index $(expr $index + ) # 交换数组元素位置。
fi
let "index += 1"
done # 内部循环结束。
let "n -= 1" # 外部循环计数减 。
# 输出每轮排序后的结果。
echo "${myArr[*]}"
done # 外部循环结束。 echo "Sorted data order:"
echo "${myArr[*]}"
参考:
《高级 Bash 脚本编程指南》
Bash : 冒泡排序的更多相关文章
- shell数组应用
引言 在Linux平台上工作,我们经常需要使用shell来编写一些有用.有意义的脚本程序.有时,会经常使用shell数组.那么,shell中的数组是怎么表现的呢,又是怎么定义的呢?接下来逐一的进行讲解 ...
- shell编程-1到100的求和与冒泡排序
Shell编程 一. for循环 生成列表 {起始数..结束数} 命令生成列表 `seq [起始数] [步进长度] 结束数 ` for l in {1..5};do for l in `seq ...
- python-Day5-深入正则表达式--冒泡排序-时间复杂度 --常用模块学习:自定义模块--random模块:随机验证码--time & datetime模块
正则表达式 语法: mport re #导入模块名 p = re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0 ...
- python开发学习-day05(正则深入、冒泡排序算法、自定义模块、常用标准模块)
s12-20160130-day05 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- Python函数的冒泡排序、递归以及装饰器
函数的冒泡排序: 本质是,让元素换位置,逐个比较最终排序. 例1:实现a1,a2值互换: a1 = 123 a2 = 456 temp = a1 a1 = a2 a2 = temp print(a1) ...
- acm之简单博弈 Nim Bash Wythoff
前些日子我打算开了博弈基础,事后想进行总结下 一句话就是分析必胜或必败,异或为0. 以下内容来自转载: Nim游戏的概述: 还记得这个游戏吗?给出n列珍珠,两人轮流取珍珠,每次在某一列中取至少1颗珍珠 ...
- Bash脚本编程之数组
数组简介 在bash脚本编程当中,变量是存储单个元素的内存空间:而数组是存储多个元素的一段连续的内存空间. 数组由数组名和下标构成,如下. ARRAY_NAME[SUBSCRIPT] 数组按照下标的类 ...
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)
本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...
随机推荐
- javascript中的异步编程
正常情况下js都是顺序执行的,但是也有很多场景下实际上是异步操作: 1.定时器都是异步操作 2.事件绑定都是异步操作 3.AJAX中一般我们都采取异步操作(也可以同步) 4.回调函数可以理解为异步(不 ...
- [20171113]修改表结构删除列相关问题.txt
[20171113]修改表结构删除列相关问题.txt --//维护表结构删除字段一般都是先ALTER TABLE <table_name> SET UNUSED (<column_n ...
- 转:IIS 应用程序池 内存 自动回收
原文地址:https://www.cnblogs.com/guohu/p/5209209.html IIS可以设置定时自动回收,默认回收是1740分钟,也就是29小时.IIS自动回收相当于服务器IIS ...
- 如何使用C语言的面向对象
我们都知道,C++才是面向对象的语言,但是C语言是否能使用面向对象的功能? (1)继承性 typedef struct _parent { int data_parent; }Parent; type ...
- idea 修改单个文件的 编码格式
- Decentraleyes - Local emulation of Content Delivery Networks
Decentraleyes, 是一个本地化第三方库文件的浏览器插件,提供三十多种语言支持.大致原理如下: 保存常用的第三方库文件到本地,当打开的页面中需要加载的第三方库文件在本地有副本时,随即进行拦截 ...
- call()和apply()
call()和apply()方法类似,区别是,call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组. 当一个函数在其主体中使用 this 关键字时,可以通过使用 ...
- 中介模型,cbv视图,和查询优化
中介模型: 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField 就可以了.但是,有时你可能需要关联数据到两个模型之间的关系上. 例如,有这 ...
- Ubuntu18.04安装Tensorflow+cuda+cuDNN
本文写的比较简单,期间遇到的一些小麻烦,自己不认为成为阻碍,所以没有详细写. 如有疑问可以联系QQ:2922530320 Pycharm Pycharm使用Anaconda Pycharm 在新建项目 ...
- Excel中row函数的使用方法
1.row函数的含义 1 row函数的含义 返回所选择的某一个单元格的行数. END 2.row函数的语法格式 1 row函数的语法格式 =row(reference) 如果省略reference,则 ...