shell中那些令人头痛的数组

一、数组

1、数组的定义

注意:在shell语句中,使用、遍历数组的时候,数组格式要写成 ${arr[@]} 或 ${arr[*]}

图示:
在这里插入图片描述

2、定义数组的方法

1  法一:#默认数组下标从0开始
数组名=(value0 value1 value2 ... 

在这里插入图片描述

2   方法二:
#数组下标索引可以自己设置
数组名=[0]=value [1]=value [2]=value ... 

在这里插入图片描述

3  
方法三:
先定义列表名,再转成数组
列表名="value0 value1 value2 ..."
数组名=($列表名)

在这里插入图片描述

4
方法四:
#一般用于for/while循环进行复制
数组名[0]="value"
数组名[1]="value"
数组名[2]="value"

在这里插入图片描述

3、数组的数据类型

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

4、获取数组长度

aa=(1 2 3 4 5)
echo ${#aa[*]}      
# echo ${#数组名[*]}  echo ${#数组名[@]}

在这里插入图片描述

5、获取数据列表

数组名=(元素0  元素1  元素2  ……)					定义数组
echo ${数组名[*]}    echo ${数组名[@]}			获取数据列表可以用echo ${数组名[*]}或echo ${数组名[@]}

在这里插入图片描述

6、获取某下标赋值

数组名=(元素0  元素1  元素2  ……)					定义数组
echo ${数组名[索引值]}							输出数组索引值对应的元素,索引值为从0开始		

在这里插入图片描述

数组的常用操作

1、遍历

#!/bin/bash
bb=(10 20 30 40 50)					定义数组
for i in ${bb[@]}						for循环将数组arr内的元素依次赋值给变量i
do
	echo $i								依次输出变量i的值						
done

在这里插入图片描述
在这里插入图片描述

2、切片

数组名=(元素0  元素1  元素2  ……)			#定义数组
echo ${bb[@]}			#输出整个数组

echo ${bb[@]:索引下标:长度}		#获取${数组名[@或*]:起始位置的索引下标:长度}的元素的值
echo ${bb[*]:索引下标:长度}				

在这里插入图片描述

3、替换

数组名=(元素0  元素1  元素2  ……)			定义数组

echo  ${数组名[@或*]/查找字符/替换字符}		${数组名[@或*]/要查找的字符/要替换的字符}
echo ${数组名[*]}						输出整个数组,并不会替换数组原有内容

数组名=(数组名{*}/查找字符/替换字符)		要实现改变原有数组,可以通过重新赋值实现
echo ${数组名[*]}						输出整个数组,替换数组原有内容

在这里插入图片描述

4、删除

数组名=(元素0  元素1  元素2  ……)					定义数组
unset 数组名[索引下标]								删除数组中索引下标所对应的的元素
unset  数组名									删除整个数组

在这里插入图片描述

5、数组追加元素

【方法一】
直接赋值,index是数组中的新下标
array_name[index]=value


【方法二】
和方法一一样,用${#}获取数组长度作为新增的数组下标
array_name[${#array_name[@]}] =value


【方法三】
在现有数组的基础上,在后面追加元素,赋给新数组
array_name=("${array_name[@]}" value1 ... valueN)

注意,使用方法三时:
1. 参数中的 双引号不能省略,否则,当数组 array_name 中包含空格的元素时会按空格将元素拆分成多个
2. 也不能将 [@] 替换成 [*] ,如果替换为 [*],不加双引号时与 [@] 时的表现一致
   加双引号时,会将数组array_name中的所有元素作为一个元素添加到数组中。
   
   
【方法四】
在现有数组的基础上,在后面追加元素
array_name+=(value1 ... valueN)
注意:待添加元素必须用 () 括号包围起来,并且多个元素用空格分隔

在这里插入图片描述

6、向函数传数组参数

注意:如果只将数组名作为变量传给函数,函数只会取数组变量的第一个元素。

1.先将数组拆分成列表   ${arr[@]}
2.函数通过$@获取之前将数组拆分成的列表   $@
3.在函数中重新把列表定义成数组 		newarr=$@)
4.对新的数组进行进一步的处理,在echo输出
#!/bin/bash
test () {
	echo "函数接收到的参数列表为:$@"				$@代表参数列表$arr
	newarr=($1)
	echo "函数中新的数组的值为:${newarr[@]}"
}

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

test $arr


在这里插入图片描述
在这里插入图片描述

7、从函数返回数组

#!/bin/bash
#从函数返回数组

#用于求数组中所有元素值得累加和
test1 () {
        newarr=($@)
        arrlist=${newarr[*]}
        sum=0

        for i in $arrlist
        do
                sum=$[sum+i]
        done
        echo $sum
}


#用于把原数组中所有的元素值乘2后生成一个新的数组并输出
test2 (){
        newarr1=($@)
        length=${#newarr1[@]}
        for ((j=0;j<=$length-1;j++))
        do
                newarr1[$j]=$[${newarr1[$j]}*2]
        done

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

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

res2=$(test2 ${array[@]})
echo "test2中的新数组的值为:$res2"


在这里插入图片描述
在这里插入图片描述

三、数组排序算法

1、冒泡排序

比较两个相邻的元素,将值大的元素交换到右边
依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面
在这里插入图片描述

#arr=(8 5 9 3 4)
read -p "请输入一个数组:" arry

#列表转数组,获取数组长度
arr=($arry)
length=${#arr[@]}

#定义比较轮数,长度-1,比如五个数,比较四轮即可
for ((i=1; i<$length; i++))
do
        #确定内次比较的次数,随着i的增大而降低,因为每轮比较后,最大/小的数已经在末尾了
        for((j=0; j<$length-$i; j++))
        do
                #获取每次用于比较的第一个、第二个数
                first=${arr[$j]}
                k=$[$j+1]
                second=${arr[$k]}
                #比较,如果前一个比后一个数大,则替换,如果是 if [ $first -lt $second ];then,则从大到小排序
                if [ $first -gt $second ];then
                        tem=${arr[$j]}
                        arr[$j]=${arr[$[$j+1]]}
                        arr[$[$j+1]]=$tem
                fi

        done
done

echo "从小到大排序为:"${arr[@]}


在这里插入图片描述
在这里插入图片描述

2、直接选择排序

基本思想:

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

#直接选择排序函数
function selectsort(){
	#列表转换成数组
	arr=($@)
	length=${#arr[@]}
	
	for((i=1; i<$length; i++))       #定义排序轮训次数,比如五个数只要排序四趟
	do
		index=0
		#确定当前排序 实际最大元素的下标,从第二个元素开始比较,每次都比上次少比一次
		for((j=1; j<=length-i; j++))
		do
			if [ ${arr[$j]} -gt ${arr[$index]} ];then     #如果是从大到小,用 -lt
				index=$j	#如果下一个比当前index大,就把大的值给index
			fi
		done
		#遍历完成,此时下标为index的 就是当前最大的元素
		#把当前比出来的index元素的值 和当前轮循的最后一个元素进行替换
		k=$[$length-$i]
		tmp=${arr[$k]}
		arr[$k]=${arr[$index]}
		arr[$index]=$tmp
	done
	#别忘了返回数组
	echo ${arr[@]}
}

########## mian ##########
read -p "请输入一个数组:" arry
#将列表传给选择排序函数,并获取返回的数组值
select_rest=`selectsort $arry`
echo "选择排序后的数组为:"${select_rest[@]}

在这里插入图片描述

在这里插入图片描述

3、反转排序

基本思想
把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,依次类推,直到把所有数组元素反转替换

#数组反转函数
function reversal(){
        arr=($@)
        length=${#arr[@]}
        for((i=0; i<$length/2; i++))
        do
                #第一个与倒数第一个替换,第二个与倒数第二个替换
                tmp=${arr[$i]}
                arr[$i]=${arr[$length-1-i]}
                arr[$length-1-i]=$tmp
        done
        echo ${arr[@]}
}

#############main##########
read -p "请输入一个数组:" arry
result=`reversal $arry`
echo "反转后的数组为:"${result[@]}

在这里插入图片描述
在这里插入图片描述

4、希尔排序

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

#!/bin/bash

arr=(7 6 8 3 1 5 2 4)
echo "当前数组元素顺序为:${arr[@]}"
length=${#arr[*]}
#把距离为gap的元素编为一个组,扫描所有组,每次循环减少增量
for ((gpg=$length/2;gpg>0;gpg/=2))
do
        #对距离为gpg的元素进行排序,每一轮比较拿当前轮次最后一个元素与组内其他元素比较,将数组大的放在后面 
        for((i=gpg;i<length;i++))
        do
                temp=${arr[$i]} 
                for ((j=i-gpg;j>=0&&temp<${arr[$j]};j-=gpg))
                do
                   arr[$j+$gpg]=${arr[$j]}
                done
                  #和最左边较大的元素调换位置
                   arr[$j+$gpg]=$temp
        done
done
echo "排序后的数组元素顺序为:${arr[*]}"

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值