shell脚本——数组的应用及排序算法(冒泡、直接、反转、希尔排序)

shell脚本——数组的应用及排序算法(冒泡、直接、反转、希尔排序)

一、字符串与列表回顾(注意与数组区分)

1、i=“11 22 33 44” ##列表
2、i=“11223344” ##字符串

image-20220707173051747

二、数组

1、数组定义方法

(30 20 10 60 50 40)
0 1 2 3 4 5

-------方法一-------
数组名=(value0 value1 value2 …)

-------方法二--------
数组名=([0]=value [1]=value [2]=value)

-------方法三--------
列表名=“value0 value1 value2…”
数组名=($列表名)

--------方法四--------
数组名[0]=“value”
数组名[1]=“value”
数组名[2]=“value”

2、数组包括的数据类型

数值类型
字符类型:使用" "或’ '定义

3、获取数组长度

[root@yu]# arr=(1 2 3 4 5 6)
[root@yu]# length=KaTeX parse error: Expected '}', got '#' at position 2: {#̲arr[*]} [root@y…{#arr[@]}
[root@yu]# echo $length

image-20220711170120465

4、获取数组列表

[root@yu]# echo ${arr[*]}
1 2 3 4 5 6
[root@yu]# echo ${arr[@]}
1 2 3 4 5 6

image-20220711170341339

5、读取某下标赋值

[root@yu ~]# echo ${arr[0]}
1
[root@yu ~]# echo ${arr[2]}
3
image-20220711170459389

6、数组遍历

[root@yu ~]# arrlist=${arr[*]}
[root@yu ~]# echo $arrlist
1 2 3 4 5 6
[root@yu ~]# for i in $arrlist

do
echo $i
done

image-20220711172034199

7、数组切片

[root@yu ~]# echo $arrlist #输出整个数组
1 2 3 4 5 6
[root@yu ~]# echo KaTeX parse error: Expected '}', got '#' at position 13: {arr[*]:2:1 #̲获取{数组名[@或*]/查找字符/替换字符}
3
[root@yu ~]# echo ${arr[@]:2:1}
3
[root@yu ~]# echo ${arr[@]:1:3}
2 3 4

image-20220711172641050

在切片的时候,先将数组输出一遍,在内部进行下标赋值,与外部无关,所有没有元素也可以输出

8、数组替换

替换仅仅是临时替换,重新替换需要重新赋值

arr=(1 2 3 4 5)

echo KaTeX parse error: Expected 'EOF', got '#' at position 19: …r[@]/4/66} #̲{数组名[@或*]/查找字符/替换字符}把4的字符替换成66
echo ${arr[@] } #并不会替换数组原有内容

arr= (${arr[@]/4/66}) #要实现改变原有数组,可通过重新赋值实现
echo ${arr[@]}

9、数组删除

arr=(1 2 3 4 5)
unset arr #删除数组
echo ${arr[*]}

arr=(1 2 3 4 5)
unset arr [2] #删除第三个元素
echo ${arr[*]}
image-20220711183002509

10、数组追加元素

---------方法一--------
array_ name [index]-value

----------方法二--------
array_ name[${#array_ name[@]}]=value

-----------方法三-----------
array_ name= (“${array_ name[@]}” value1 … valueN)
#双引号不能省略,否则,当数组array_name中存在包含空格的元素时会按空格将元素拆分成多个
#不能将“@”替换为“”,如果替换为“”,不加双引号时与“@"的表现一*致, 加双引号时,会将数组array_ name中的所有元素作为一个 元素添加到数组中

for i in “${array_ name[@]}”; do echo $i; done

------------方法四------------
array_ name+= (value1 …valueN)
#待添加元素必须用“()"包围起来,并且多个元素用空格分隔

11、向函数传数组参数

代码清单

image-20220712142839530

解决这个问题则需要将数组变量的值分解成单个的值,然后将这些值作为函数参数使用

代码清单

#!/bin/bash

test1 (){
echo ""函数接收到的参数列表为: @ n e w a r r = ( @ newarr=( @newarr=(@)
echo “函数中新的数组的值为:${newarr[*]}”
}

#####main####

arr=(30 10 20 50 40)
echo “原始的数组列表为:${arr[@]}”

test1 ${arr[*]}
#test1 30 10 20 50 40

[root@localhost ~]# vim cc.sh
[root@localhost ~]# chmod +x *
[root@localhost ~]# ./cc.sh
原始的数组列表为:30 10 20 50 40
函数接收到的参数列表为:30 10 20 50 40
函数中新的数组的值为:30 10 20 50 40

image-20220717234829915

1、先将数组拆分成列表 ${arr[@]}

2、函数通过$@获取之前将数组拆分成的列表 @ 3 、 在 函 数 中 重 新 把 列 表 定 义 成 数 组 n e w a r r = ( @ 3、在函数中重新把列表定义成数组 newarr=(@3、在函数中重新把列表定义成数组newarr=(@0)
4、对新的数组进行进一步的处理

12 、从函数中返回数组

代码清单

[root@localhost ~]# vim fanhui.sh

    for i in $arrlist
    do
            sum=$[$sum + $i]   #循环累加
    done
    echo $sum

}

#用于把原数组中所有的元素值2后生成一个新的数组并输出
test2 (){
newarr1=( @ ) l e n g t h = @) length= @)length={#newarr1[
]}
for ((j=0; j<= l e n g t h − 1 ; j + + ) ) d o n e w a r r 1 [ length-1; j++)) do newarr1[ length1;j++))donewarr1[j]= [ [ [{newarr1[$j]} * 2]
done
echo ${newarr1[*]}
}

#####main#####
array=(10 20 30 40 50)
echo “原数组的列表为:${array[@]}”

res1=test1 ${array[@]}
echo “test1新数组的累加和为:$res1”

res2=$(test2 a r r a y [ @ ] ) e c h o " t e s t 2 中的新数组的值为: {array[@]}) echo "test2中的新数组的值为: array[@])echo"test2中的新数组的值为:res2"

image-20220717235010770

image-20220717235029590

三、数组排序算法

1、冒泡排序法

类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断地向前移动

基本思想
冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部。

算法思路
冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。

代码清单

[root@localhost ~]# vim maopao.sh
[root@localhost ~]# cat maopao.sh
#!/bin/bash
read -p “请输入一个数组列表:” list
#定义一个初始数组
arr=( l i s t ) e c h o " 原数组的顺序为: list) echo "原数组的顺序为: list)echo"原数组的顺序为:{arr[@]}"
#获取数组的长度
length=${#arr[@]}

#冒泡排序:
#定义比较轮数,为数组长度减1,并且要从1开始
for ((i=1; i<KaTeX parse error: Expected 'EOF', got '#' at position 19: …gth; i++)) do #̲确定每次比较的元素下标,比较相…length-KaTeX parse error: Expected 'EOF', got '#' at position 16: i; j++)) do #̲获取第一个元素的值 fir…{arr[KaTeX parse error: Expected 'EOF', got '}' at position 3: j]}̲ #获取第二个元素的值 …j+1
second=KaTeX parse error: Expected '}', got 'EOF' at end of input: {arr[k]}
#比较第一个元素和第二个元素的值,如果第一个元素的值大于第二个元素的值,则两个元素交换位置
if [ $first -gt KaTeX parse error: Expected 'EOF', got '#' at position 17: …econd ];then #̲先把第一个元素的值保存在临时变…{arr[KaTeX parse error: Expected 'EOF', got '}' at position 3: j]}̲ #把第二个元素的值赋给第…j]=KaTeX parse error: Expected 'EOF', got '#' at position 10: second #̲把原来第一个元素的值赋给第二个…k]= t e m p f i d o n e d o n e e c h o " 排序后新的数组的顺序为: temp fi done done echo "排序后新的数组的顺序为: tempfidonedoneecho"排序后新的数组的顺序为:{arr[*]}"

[root@localhost ~]# vim maopao.sh
[root@localhost ~]# ./maopao.sh
请输入一个数组列表:10 40 60 80 50
原数组的顺序为:10 40 60 80 50
排序后新的数组的顺序为:10 40 50 60 80
[root@localhost ~]# ./maopao.sh
请输入一个数组列表:60 40 30 90 10
原数组的顺序为:60 40 30 90 10
排序后新的数组的顺序为:10 30 40 60 90

2、直接排序法

与冒泡排序相比,直接选择排序的交换次数更少,所以速度更快

基本思想

将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值,注意这里区分冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。

代码清单

[root@localhost ~]# vim zhijie.sh
[root@localhost ~]# ./zhijie.sh
请输入一个数值列表:20 50 60 10 90
原始数组的顺序为:20 50 60 10 90
排序后的新数组的顺序为:10 20 50 60 90
[root@localhost ~]# vim zhijie.sh

#!/bin/bash
read -p “请输入一个数值列表:” list
arr=( l i s t ) l e n g t h = list) length= list)length={#arr[@]}
echo “原始数组的顺序为:${arr[@]}”

#定义排序轮数
for ((i=1; i<KaTeX parse error: Expected 'EOF', got '#' at position 26: …+)) do #̲先假设最大的元素下标为0 …length-$i; j++))
do
if [ KaTeX parse error: Expected '}', got 'EOF' at end of input: {arr[j]} -gt KaTeX parse error: Expected '}', got 'EOF' at end of input: {arr[index]} ];then
index=$j
fi
done
#在确定好当前轮次的最大元素下标后,开始最大元素的值和当前轮次最后一个元素进行交换

    #获取每轮最后一个元素的索引
    last=$[$length - $i ]
    #把当前轮次的最后一个元素的值保存在临时变量中
    temp=${arr[$last]}
    #把最大的元素的值赋给最后一个元素
    arr[$last]=${arr[$index]}
    #把原最后一个元素的值赋给原最大值的位置的元素
    arr[$index]=$temp

done
echo “排序后的新数组的顺序为:${arr[@]}”

3、反转排序

以相反的顺序把原有数组的内容重新排序

基本思想

把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有的数组元素反转替换。

代码清单

[root@localhost ~]# vim fanzhuan.sh
[root@localhost ~]# chmod +x *
[root@localhost ~]# ./fanzhuan.sh
70 60 50 40 30 20 10
[root@localhost ~]# vim fanzhuan.sh

#!/bin/bash

arr=(10 20 30 40 50 60 70)
length=${#arr[@]}

for ((i=0; i<length/2; i++))
do
temp=KaTeX parse error: Expected '}', got 'EOF' at end of input: {arr[i]}
arr[ i ] = i]= i]={arr[ l e n g t h − length- lengthi-1]}
arr[ l e n g t h − length- lengthi-1]=$temp
done

echo ${arr[@]}

image-20220717235306943

image-20220717235322926

4、希尔排序(仅作了解)

希尔排序(Shell Sort)是插入排序的一种算法,是对直接插入排序的一个优化,也称缩小增量排序。
原理
希尔排序是将待排序的数组元素 按下标的一定增量分组 ,分成多个子序列,然后对各个子序列进行直接插入排序算法排序;然后依次缩减增量再进行排序,直到增量为1时,进行最后一次直接插入排序,排序结束。

增量d 的范围: 1<= d < 待排序数组的长度 (d 需为 int 值)
增量的取值:一般的初次取序列(数组)的一半为增量,以后每次减半,直到增量为1
第一个增量=数组的长度/2
第二个增量= 第一个增量/2
第三个增量=第二个增量/2
以此类推,最后一个增量=1

image-20220717235515217

代码清单

#!/bin/bash
array=(7 6 8 3 1 5 2 4)
length=${#array[*]}

#把距离为gap的元素编为一组,扫描所有的组,每次循环减少增量
for ((gap= l e n g t h / 2 ; g a p > 0 ; g a p / = 2 ) ) d o f o r ( ( i = g a p ; i < length/2; gap>0; gap/=2)) do for ((i=gap; i< length/2;gap>0;gap/=2))dofor((i=gap;i<length; i++))
do
temp=KaTeX parse error: Expected '}', got 'EOF' at end of input: {array[i]}
#对距离为gap的元素组进行排序,每一轮比较拿当前轮次最后一个元素与组内其他元素比较,将数组大的往后放
for ((j=i-gap; j>=0&&temp<KaTeX parse error: Expected '}', got 'EOF' at end of input: {array[j]}; j-=gap))
do
array[ j + j+ j+gap]=KaTeX parse error: Expected '}', got 'EOF' at end of input: {array[j]}
done
#和左边较大的元素调换位置
array[ j + j+ j+gap]=$temp
done
done
echo ${array[*]}

[root@localhost ~]# vim xier.sh
[root@localhost ~]# chmod +x *
[root@localhost ~]# ./xier.sh
1 2 3 4 5 6 7 8

image-20220717235550329

分析思路

7 6 8 3 1 5 2 4
gap=(8+1)/2=4时比较,大的放后面
7-1 -> 1-7
6-5 -> 5-6
8-2 -> 2-8
3-4 -> 3-4

1 5 2 3 7 6 8 4
gap=4/2=2时比较
1 2 7 8
1 2->1 2
1 2 7–>1 2 7
1 2 7 8—>1 2 7 8

5 3 6 4 每一轮比较拿当前轮次最后一个元素与组内其他元素比较,将数组大的往后放
5 3->3 5
3 5 6–>3 5 6
3 5 6 4—>3 4 5 6

1 3 2 4 7 5 8 6
gap=2/2=1时比较
1 3->1 3
1 3 2–>1 2 3
1 2 3 4—>1 2 3 4
1 2 3 4 7---->1 2 3 4 7
1 2 3 4 7 5----->1 2 3 4 5 7
1 2 3 4 5 7 8------>1 2 3 4 5 7 8
1 2 3 4 5 7 8 6------->1 2 3 4 5 6 7 8

1 5 2 3 7 6 9 4

gap=2

i=2 i<7 i++
temp=${array[2]}=2

j=2-2=0 2<1 …

i=3
temp= a r r a y [ 3 ] = 3 j = 3 − 2 = 13 < 5 a r r a y [ 3 ] = {array[3]}=3 j=3-2=1 3<5 array[3]= array[3]=3j=32=13<5array[3]={array[1]}=5
j=1-2=-1 …
array[-1+2]=3

1 3 2 5 7 6 9 4
gap=2

i=4
temp=${array[4]}=7
j=4-2=2 7<2…

i=5
temp=${array[5]}=6
j=5-2=3 6<5…

i=6
temp=${array[6]}=9
j=6-2=4 9<7…

1 3 2 5 7 6 9 4
i=7
temp= a r r a y [ 7 ] = 4 j = 7 − 2 = 54 < 6 a r r a y [ 5 + 2 ] = {array[7]}=4 j=7-2=5 4<6 array[5+2]= array[7]=4j=72=54<6array[5+2]={array[5]}=6
1 3 2 5 7 6 9 6
j=5-2=3 4<5
array[3+2]=${array[3]}=5
1 3 2 5 7 5 9 6
j=3-2=1 4<3…
array[1+2]=4
1 3 2 4 7 5 9 6

++
temp=${array[2]}=2

j=2-2=0 2<1 …

i=3
temp= a r r a y [ 3 ] = 3 j = 3 − 2 = 13 < 5 a r r a y [ 3 ] = {array[3]}=3 j=3-2=1 3<5 array[3]= array[3]=3j=32=13<5array[3]={array[1]}=5
j=1-2=-1 …
array[-1+2]=3

1 3 2 5 7 6 9 4
gap=2

i=4
temp=${array[4]}=7
j=4-2=2 7<2…

i=5
temp=${array[5]}=6
j=5-2=3 6<5…

i=6
temp=${array[6]}=9
j=6-2=4 9<7…

1 3 2 5 7 6 9 4
i=7
temp= a r r a y [ 7 ] = 4 j = 7 − 2 = 54 < 6 a r r a y [ 5 + 2 ] = {array[7]}=4 j=7-2=5 4<6 array[5+2]= array[7]=4j=72=54<6array[5+2]={array[5]}=6
1 3 2 5 7 6 9 6
j=5-2=3 4<5
array[3+2]=${array[3]}=5
1 3 2 5 7 5 9 6
j=3-2=1 4<3…
array[1+2]=4
1 3 2 4 7 5 9 6

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值