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查找,还包括数结构的二叉排序树以 ...
随机推荐
- git svn 流程
$ git svn clone http://192.168.10.208/svn/DeptDoc $ git svn rebase $ git commit -asm "svn tra ...
- windows7下的一个好玩的,你绝对不知道
今天学到了一个好东西,分享一下, windows7系统测试是可以的,其他系统暂时没测试,分享给大家玩玩: 在桌面新建一个文件夹: 文件夹重命名为:GodMode.{ED7BA470-8E54-465E ...
- macOS平台安装metasploit
1 在Github上克隆Metasploit git clone https://github.com/rapid7/metasploit-framework.git /usr/local/shar ...
- ccf--20160403---路径解析
本题思路如下: 具体的细节如下:首先去掉字符串中重复出现的/,然后遇到..,就删除栈的最后一个元素,.忽略 下面是代码和题目: 问题描述 试题编号: 201604-3 试题名称: 路径解析 时间限制: ...
- 最后一个单词的长度的golang实现
给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度. 如果不存在最后一个单词,请返回 0 . 说明:一个单词是指由字母组成,但不包含任何空格的字符串. 输入: "He ...
- flex布局下el-table横向滚动条失效
如下图,是一种常见的页面结构,我们可以有很多方法实现,inline-block,float,flex等等 但是,最近项目中遇到一个怪事,左边是侧边栏导航,右边是一个数据展示table,el-table ...
- RESTful API实战笔记(接口设计及Java后端实现)
写在前面的话 原计划这部分代码的更新也是上传到ssm-demo仓库中,因为如下原因并没有这么做: 有些使用了该项目的朋友建议重新创建一个仓库,因为原来仓库中的项目太多,结构多少有些乱糟糟的. 而且这次 ...
- 安装docker后访问外网失败
服务器网段是(172.17)与docker默认桥接的网桥号段相同 docker version 17.03.2-ce 1.centOS6 原文链接 http://www.bubuko.com/info ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 1: ordinal not in range(128)
对于写python的人来说,这个异常一点不陌生,只要涉及到中文字符串的操作,一不小心就会出错.关于这个问题的解释,找到一篇好文,分享一下. 原文地址:https://blog.csdn.net/u01 ...
- ASP 基础三 SQL指令
一 增删改查 <% set conn=server.CreateObject("adodb.connection") DSNtemp="DRIVER={SQL Se ...