“Shell“八大排序算法(冒泡排序 .直接插入排序 .直接选择排序 .希尔排序)

八大排序算法:

在这里插入图片描述

1.冒泡排序

冒泡排序,该排序的命名非常形象,即一个个将气泡冒出。冒泡排序一趟冒出一个最大(或最小)值。
在这里插入图片描述
基本思想:

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

算法思路:

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

实验:

#!/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
       ##获取相邻两个元素的前面的元素的值
       first=${
    
    arr[$b]}
       ##获取相邻两个元素的后面元素的值
       c=$[b + 1]
       second=${
    
    arr[$c]}
       ##比较两个相邻元素的值的大小,如果前面元素的值较大,则与>
后面元素交换位置
       if [ $first -gt $second ];then
           ##使用临时变量保存前面元素的值,实现两个相邻元素交换>位置
       tmp=$first
       arr[$b]=$second
       arr[$c]=$tmp
       fi
     done
done
echo "冒泡排序后的数组的值为: ${arr[@]}"

实验结果:

在这里插入图片描述

2.直接插入排序

插入排序,又叫直接插入排序。实际中,我们玩扑克牌的时候,就用了插入排序的思想。
在这里插入图片描述

扫描二维码关注公众号,回复: 15352176 查看本文章

基本思想:

  • 在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行插入,直到整个序列有序。
  • 但我们并不能确定待排元素中究竟哪一部分是有序的,所以我们一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止。

实验:

#!/bin/bash

arr=(63 4 24 1 3 15)
echo "排序前数组的值为:${arr[@]}"

length=${
    
    #arr[@]}
#外层循环定义待排序的元素下标位置
for ((b=0; 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[@]}"

实验结果:
在这里插入图片描述

3.直接选择排序

与冒号排序相比,直接选择排序的交换次数更少,所以速度会更快
在这里插入图片描述选择排序,即每次从待排序列中选出一个最小值,然后放在序列的起始位置,直到全部待排数据排完即可。

基本思想:

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

第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零,选择排序是一种不稳定的排序方法。

实验:

#!/bin/bash
arr=(63 4 24 1 3 15)
echo "排序前数组的值为:${arr[@]}"

length=${
    
    #arr[@]}
##外层循环定义待排序的元素下标位置
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[@]}"

实验结果:

在这里插入图片描述

4.希尔排序

希尔排序是按其设计者希尔的名字命名的,该算法由希尔1959年公布。希尔可以说是一个脑洞非常大的人,他对普通插入排序的时间复杂度进行分析,得出了以下结论:

  • 1.普通插入排序的时间复杂度最坏情况下为O(N2),此时待排序列为逆序,或者说接近逆序。
  • 2.普通插入排序的时间复杂度最好情况下为O(N),此时待排序列为升序,或者说接近升序。

于是希尔就想:若是能先将待排序列进行一次预排序,使待排序列接近有序(接近我们想要的顺序),然后再对该序列进行一次直接插入排序。因为此时直接插入排序的时间复杂度为O(N),那么只要控制预排序阶段的时间复杂度不超过O(N2),那么整体的时间复杂度就比直接插入排序的时间复杂度低了。
在这里插入图片描述
基本思想:

1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作…
2.当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。
注:一般情况下,取序列的一半作为增量,然后依次减半,直到增量为1(也可自己设置)。

实验:

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

#把距离为gap的元素编为一个组,扫描所有组,每次循环减少增量
for ((gap=$length/2; gap>0; gap/=2))
do
    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[*]}

实验结果:

在这里插入图片描述

实验:反转排序

实验:

#!/bin/bash
arr=(1 2 3 4 5 6 7 8 9)
echo "排序前数组的值为: ${arr[@]}"

length=${
    
    #arr[@]}
for  ((a=0; a<length/2; a++))
do
   tmp=${
    
    arr[$a]}
   ##获取当前轮数的最后一共元素下标,会随着轮数的增加而减少
   last=$[length-1-a]
   arr[$a]=${
    
    arr[$last]}
   arr[$last]=$tmp

done
echo "排序后数组的值为: ${arr[@]}"

实验结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Wanghwei17/article/details/130599223