数组排序算法

183 阅读3分钟

冒泡排序

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

基本思想:

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

算法思路

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

Snipaste_2022-09-02_14-47-40.png

#!/bin/bash
arr=(63 4 24 1 3 15)
echo "原数组元素列表顺序为:${arr[@]}"
length=${#arr[@]} ##获得数组的长度#使用外部循环定义比较轮数,比较轮数为数组长度减1,且从1开始
for ((a=1;a<$length;a++))
do
  #使用内部循环来进行相邻两个元素的比较,确定元素的位置,较大的数往后放,且每轮的比较次数会随着比较轮数而减少
  #这里内部循环的变量用来表示两个相邻比较元素的前一个元素的下标
  for((b=0;b<$length-a;b++))
  do
     ##定义left两个相邻比较元素的前一个元素的值
     left=${arr[$b]}
     #定义right变量获取两个相邻比较元素的后一个元素的值
     c=$[b+1]
     right=${arr[$c]}
     ##将两个相邻元素的值进行比较,如果前一个的值较大则两个元素互换值
     if [ $left -gt $right];then
          tmp=$left  ##tmp临时变量
          arr[$b]=$right
          arr[$c]=$tmp
     if
  done
done
echo "排序后数组的顺序为:${arr[@]}"

Snipaste_2022-09-02_14-03-31.png

直接选择排序

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

基本思想

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

Snipaste_2022-09-02_14-45-51.png
#!/bin/bash
#直接选择排序,实现升序
​
arr=(63 4 24 1 3 15)
echo "原数组元素列表顺序为:${arr[@]}"
length=${#arr[@]}#定义排序轮数,为数组长度减1
for ((a=1;a<$length;a++))
do
   #初始定义假设下标为0的元素的值最大
   n=0 
   #定义内循环变量为从第二个元素下标开始,用于比较当前假设的最大元素的值,并记录最大元素下标
   for((b=1;b<=length-a;b++))
   do
       if [ ${arr[$b]} -gt ${arr[$n]} ];then
          n=$b
       fi
   done
   #获取每轮最后一个比较元素的下标
   last=$[length - a]
   #拿最大的元素和当前轮数的最后一个比较元素交换值
   tmp=${arr[$last]}
   arr[$last]=${arr[$n]}
   arr[$n]=$tmp
done
echo "排序后的数组顺序为:${arr[@]}"

Snipaste_2022-09-02_14-05-33.png

反转排序

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

基本思想:

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

#!/bin/bash
#反转排序
arr=(10 20 30 40 50 60 70 80)
length=${#arr[@]}  #取数组的长度#设置前后两个替换元素中的前面的元素下标的取值范围,下标从0开始
for ((a=0; a<$length/2; a++))
do
    tmp=${arr[$a]}
    #将最后一个变量赋给第一个变量
    arr[$a]=${arr[$length-1-$a]}
    #将临时变量赋给最后一个变量
    arr[$length-1-$a]=$tmp
done
echo "反转排序后的数组顺序为:${arr[@]}"

Snipaste_2022-09-02_14-06-19.png

插入排序

基本思想:

在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行插入,直到整个序列有序。

但我们并不能确定待排元素中究竟哪一部分是有序的,所以我们一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止

#!/bin/bash
#插入排序,实现升序
arr=(63 4 24 1 5 3)
length=${#arr[@]}
#定义比较的轮数,并a的值可以也用于作为待排序的元素下标
for ((a=1;a<length;a++))
do
   #定义于用于和待排序的元素比较的元素下标范围
   #拿待排序的元素和前面已排序好的元素进行比较,较大的数放后面的待排序元素的位置,较小的数放前面的位置
   for ((b=0;b<a;b++))
   do
      if [ ${arr[$a]} -lt ${arr[$b]}];then
         tmp=${arr[$a]}
         arr[$a]=${arr[$b]}
         arr[$b]=$tmp
      fi
   done
done
echo "反转排序后的数组顺序为:${arr[@]}"

Snipaste_2022-09-02_14-14-07.png