shell编程之多种排序算法及实现代码

前言

  • 对数据进行分析的时候经常需要对数据进行序处理,比如按占用CPU的时间对进程进行排序、按出现的次数频率对数据排序、按大小对数据进行排序。当然对数据排序我们可以使用sort命令,而这次我们介绍的是通过编写shell排序脚本对,对数据进行自定义排序。常见的排序算法有:冒泡排序、插入排序、选择排序、快速排序、堆排序、归并排序,希尔排序等等。

排序算法之冒泡排序

算法介绍

  • 冒泡排序是一种相对而言比较简单的排序方法。它是不断地比较相邻两个数的大小,根据大小进行排序(升序或降序)。如果顺序不对,则彼此交换位置,以此类推,当所有的数据都比较完成之后,一定可以找到最大或最小值。通过彼此交换位置慢慢地把最大或最小值浮现出来,就好比是气泡浮出水面一样,这种算法也叫作冒泡排序。

脚本演示

#!/bin/bash
#功能描述:通过输入5个数字进行比较演示冒泡排序

#使用数组存取输入的5个数
for i in `seq 5`
do
  read -p "请输入第${i}个数字:" num
  if echo $num | grep -qP "\D"; then
     echo "您输入的不是数字!"
     exit
  fi
  arri_num[$i]=$num
done
echo "您输入的数字序列为:${arri_num[@]}"

#下面进行冒泡排序,使用i控制几轮,使用j控制每轮比较次数
#5个数需要5轮比较,随着每轮的增加,下一轮的比较次数会减一次 
for ((i=1;i<=4;i++))
do
  for ((j=1;j<=$[5-i];j++))
  do
    if [ ${arri_num[j]} -gt ${arri_num[j+1]} ]; then
       num=${arri_num[j]}
       arri_num[$j]=${arri_num[j+1]}
       arri_num[j+1]=$num
    fi
  done
done
echo "经过排序之后的数字序列为:${arri_num[@]}"     
  • 脚本执行结果
    在这里插入图片描述

排序算法之快速排序

算法介绍

  • 快速排序简称快排,是在冒泡排序的基础上演变而来的算法。这个算法的主要思想就是,挑选出一个基准数字,然后把比他大的数字排在一边,再把比他小的数字排在另一边。然后递归对该基准数字两边的所有数字做相同的比较排序,直到所有数字变为有序数字。快速排序的效率取决于所选的基准数字,如果基准数字是一个比较折中的数字,则基准数字两边就比较均衡,这样比较的次数就会大大减少。如果基准数字两边的数字不均衡,最终需要进行的数字比较次数就会增多。通常我们会取第一个元素或最后一个元素作为基准数字。

脚本演示

#!/bin/bash
#功能描述:采用分治思想实现快速排序

arr=(12 8 14 6 17 9 13)

#定义一个快速排序的函数
#先判断需要进行比较的个数,$1是数组最左边的坐标,$2是数组最右边的坐标
#左边坐标要小于右边坐标,否则表示需要排序的数字只有一个,不需要排序,直接退出
quick_f () {
  if [ $1 -ge $2 ]; then
     return
  fi

#定义局部变量,base为基准数字,我们选最左边的数字arr[$1]
#i表示左边坐标,j表示右边坐标  
  local base=${arr[$1]}
  local i=$1
  local j=$2

#再要排序的数字序列中,比base大的放在左边,比base小的放在右边
  while [ $i -lt $j ]
  do
#j向左移动,查找比base大的数    
    while [[ ${arr[j]} -ge $base && $i -lt $j ]]
    do
      let j--
    done
    arr[i]=${arr[j]}
#i向右移动,查找比base小的数
    while [[ ${arr[i]} -le $base && $i -lt $j ]]
    do
      let i++
    done
    arr[j]=${arr[i]}
    #在当组执行完一次之后,将base回归到数组中
    arr[i]=$base

#递归调用快速排序算法对左右两边的元素进行快排
  quick_f $1 $[i-1]
  quick_f $[i+1] $2
}

#调用函数对数组进行排序
quick_f 0 ${#arr[@]}
echo ${arr[*]}

排序算法之插入排序

算法介绍

  • 插入排序就是提取一个数字后,对已排序的数字从前往后一次比较选择合适的位置插入。这种算法的优点就是任意一个数字可能不需要对比所有的数字就可以找到合适的位置,当然最差的情况也有可能需要对比所有的数字之后才能够确定合适的位置。通常我们默认第一个数字已经排序,然后提取下一个数字,拿这个数字从后往前跟已经排序的数字反复逐一比较,知道该数字找到合适的位置进行插入。最终得到一个有序的序列。

脚本演示

#!/bin/bash
#功能描述:插入算法排序演示。

for x in `seq 5`
do
  read -p "请输入${x}个随机整数:" num
  arr[$x]=$num
done

#直接从第二个数开始,跟前面的数字比较大小
#使用i控制需要提取的跟前面比较的数字
for ((i=2;i<=5;i++))
do
#使用j控制第i个元素前面需要比较的数字
#j从第i-1个元素开始,每次循环一次j向前移一位
#如果j<0或i>第j个元素值,跳出循环
  num=${arr[i]}
  for ((j=$[i-1];j>=0 && $num<arr[j];j--))
  do
    arr[j+1]=${arr[j]}
    arr[j]=$num
  done
done

echo "经过排序后的数字序列为:${arr[@]}"

排序算法之计数排序

算法介绍

  • 前三种算法中无论都是基于数字比较进行排序的,而计数排序是不需要进行比较进行排序的。计数排序的核心思想就是多创建一个数组,用于统计待排序数组中每个元素出现的次数。

脚本演示

#!/bin/bash
#功能描述:计数算法

#创建一个需要排序的数组
arr=(3 2 1 4 5 8 9 7 6 3 3 5 7 1 4 6 2 9)

#根据arr数组的最大值创建出一个对应空间大小的统计数组
#该数组初始值为0,即使没有数据初始值也为0
max=${arr[0]}
for i in `seq $[${#arr[@]}-1]`
do
  [ ${arr[i]} -gt $max ] && max=${arr[i]}
done

for i in `seq 0 $max`
do
  count[i]=0
done

#循环读取arr数组中的每一个元素值,以每个元素值为count数组的下标,自加1
for i in `seq 0 $[${#arr[@]}-1]`
do
  let count[${arr[i]}]++
done

#使用多从循环读取count中的每个元素值
for i in `seq 0 $[${#count[@]}-1]`
do
  for j in `seq ${count[i]}`
  do
    echo -n "$i "
  done
done
echo
  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值