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查找,还包括数结构的二叉排序树以 ...
随机推荐
- Excel表格规范
数据处理: 在数据进行分析使用时,需要去除原始数据中的脏数据,让统计数据均为有效数据: 统一表格的格式:去除空格.强制换行符 CLEAN()函数:是去除单元格中的特殊字符: TRIM()函数:去除单元 ...
- Android 接收系统广播(动态和静态)
1.标准广播:是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎会在同一时刻接收到这条广播信息,它们之间没有先后顺序.效率高.无法被截断. 2.有序广播:是一种同步执行的广播,在广播发出后 ...
- 机器学习中学习曲线的 bias vs variance 以及 数据量m
关于偏差.方差以及学习曲线为代表的诊断法: 在评估假设函数时,我们习惯将整个样本按照6:2:2的比例分割:60%训练集training set.20%交叉验证集cross validation set ...
- Linux 小知识翻译 - 「内核(kernel)」
上次介绍了Linus Torvalds, 这次介绍他开发的「内核」. 经常听人提到「Linux kernel」,但如果被问到「kernel究竟是什么?」的话,会出乎意料的觉得难以回答. 那么,kern ...
- 【2017下集美大学软工1412班_助教博客】团队作业7——第二次项目冲刺(Beta阶段)成绩公示
作业要求 团队作业7 团队评分结果 Beta计划 Total GN SX GJ LC AP WT PHILOSOPHER 3 1 0 1.5 0 0.5 0 三人行 3.5 1 1 1 0 0.5 0 ...
- jsp 一点点
jsp学习 jsp -处理 作为正常的页面,你的浏览器发送一个http请求道web服务器. web 服务器承认一个JSP页面的HTTP请求,并将其转发给一个JSP引擎. JSP引擎从磁盘加载JSP页面 ...
- 布局:高度已知,布局一个三栏布局,左栏和右栏宽度为200px,中间自适应
需求:高度已知为200px,写出三栏布局,左栏和右栏各位200px,中间自适应,如下图所示: 方法一:float浮动布局 原理是:定义三个区块,需要注意的是中间的区块放在右边区块的下面,统一设置高度为 ...
- 基于Redis的INCR实现一个限流器
模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令. 比如在一个 web 应用程序中,如果想知道 ...
- Scala 上下文界定
上下文界定的类型参数形式为T:M的形式,其中M是一个泛型,这种形式要求存在一个M[T]类型的隐式值: /** * 上下文界定 */ @Test def testOrdering_Class_Conte ...
- spring boot thymeleaf 标签未关闭报错
每天学习一点点 编程PDF电子书免费下载: http://www.shitanlife.com/code spring boot,input标签未关闭报bug,代码稍有不慎就出小问题,后来百度,goo ...