shell中的排序算法

shell中的排序算法

文章目录

  • shell中的排序算法
  • 冒泡排序法
    • 基本思想:
    • 算法思路
  • 直接选择排序
    • 基本思想:
  • 反转排序
    • 基本思想:
  • 直接插入算法
    • 基本思想:
  • 希尔算法
    • 基本思想

shell中的排序算法

冒泡排序法

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

基本思想:

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

算法思路

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

#!/bin/bash
array=(112 221 33 55 66 11 25 68)
length="${#array[@]}"
for ((i=1; i<=$length; i++))
do
  for ((j=1; j<=$length-$i; j++))
  do
    first=${array[$j]}
    k=$[$j+1]
    second=${array[$k]}
    if [ $first -gt $second ]
      then
        temp=$first
        array[$j]=$second
        array[$k]=$temp
    fi
  done
done

echo "new_array: ${array[@]}"

直接选择排序

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

基本思想:

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

#!/bin/bash
array=(77 22 99 1 23 55 11)
echo "老数组顺序为 ${array[@]}"
length=${#array[@]}

for ((i=1; i<=length; i++))
do
  index=0
  for ((j=1; j<=length-i; j++))
  do
    CURR=${array[$j]}
    MAX=${array[$index]}
    if [ $CURR -gt $MAX ]
      then
        index=$j
    fi
  done
  last=$[ $length - $i ]
  temp=${array[$last]}
  array[$last]=${array[$index]}
  array[$index]=$temp

done

echo "新数组的顺序为 ${array[@]}"

反转排序

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

基本思想:

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

#!/bin/bash
array=(1 2 3 4 5 6 7 8 9)
length=${#array[@]}
for ((i=0; i<=length/2; i++))
do
  first=${array[$i]}
  last=${array[$length-$i-1]}
  temp=$first
  array[$i]=$last
  array[$length-$i-1]=$temp
done
echo "${array[*]}"

直接插入算法

插入排序,又叫直接插入排序。实际中,我们玩扑克牌的时候,就用了插入排序的思想。

基本思想:

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

#!/bin/bash
array=(8 2 9 44 6 28 10)
echo "原数组为 ${array[*]}"
length=${#array[@]}
for ((i=1; i<=$length; i++))
do
  for ((j=0; j<=$i; j++))
    do
      if [[ ${array[$i]} -lt ${array[$j]} ]]
        then
           temp=${array[$i]}
           array[$i]=${array[$j]}
           array[$j]=$temp
      fi
    done
done

echo "新数组为 ${array[@]}"
~
~

希尔算法

希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序 。

基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作…

2.当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。

gap越大,数据挪动得越快;gap越小,数据挪动得越慢。前期让gap较大,可以让数据更快得移动到自己对应的位置附近,减少挪动次数。

#!/bin/bash
array=(8 9 1 7 2 3 5 4)
length=${#array[@]}
echo "原数组为 ${array[@]}"
#设长度的一半为gap初始间隔,每次循环gap都除以2,直至gap为1结束循环
for ((gap=$length/2; gap>0; gap/=2))
do
#因为gap为整个长度的一半,所以gap到length结尾包含的元素数刚好为需要进行直接插入算法的个数
  for ((i=gap; i<$length; i++))
    do
    #设一个第三变量方便直接插入进行交换
      temp=${array[$i]}
       #对距离为gap的元素组进行排序,每一轮比较拿当前轮次最后一个元素与组内其他元素比较,将数组大的往后放
      for((j=i-gap; j>=0&&temp<${array[$j]}; j-=gap))
        do
          array[$j+$gap]=${array[$j]}
        done
      array[$j+$gap]=$temp
    done
done

echo "新的数组为 ${array[*]}"

版权声明:如无特殊标注,文章均来自网络,本站编辑整理,转载时请以链接形式注明文章出处,请自行分辨。

本文链接:https://www.shbk5.com/dnsj/73019.html