前言
对数据进行分析的时候经常需要对数据进行序处理,比如按占用CPU的时间对进程进行排序、按出现的次数频率对数据排序、按大小对数据进行排序。当然对数据排序我们可以使用sort命令,而这次我们介绍的是通过编写shell排序脚本对,对数据进行自定义排序。常见的排序算法有:冒泡排序、插入排序、选择排序、快速排序、堆排序、归并排序,希尔排序等等。
排序算法之冒泡排序
算法介绍
冒泡排序是一种相对而言比较简单的排序方法。它是不断地比较相邻两个数的大小,根据大小进行排序(升序或降序)。如果顺序不对,则彼此交换位置,以此类推,当所有的数据都比较完成之后,一定可以找到最大或最小值。通过彼此交换位置慢慢地把最大或最小值浮现出来,就好比是气泡浮出水面一样,这种算法也叫作冒泡排序。
脚本演示
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[@]}"
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[@]}"
脚本执行结果
排序算法之快速排序
算法介绍
快速排序简称快排,是在冒泡排序的基础上演变而来的算法。这个算法的主要思想就是,挑选出一个基准数字,然后把比他大的数字排在一边,再把比他小的数字排在另一边。然后递归对该基准数字两边的所有数字做相同的比较排序,直到所有数字变为有序数字。快速排序的效率取决于所选的基准数字,如果基准数字是一个比较折中的数字,则基准数字两边就比较均衡,这样比较的次数就会大大减少。如果基准数字两边的数字不均衡,最终需要进行的数字比较次数就会增多。通常我们会取第一个元素或最后一个元素作为基准数字。
脚本演示
arr=( 12 8 14 6 17 9 13)
quick_f ( ) {
if [ $1 -ge $2 ] ; then
return
fi
local base=${ arr[ $1 ] }
local i=$1
local j=$2
while [ $i -lt $j ]
do
while [ [ ${ arr[j] } -ge $base && $i -lt $j ] ]
do
let j--
done
arr[i] =${ arr[j] }
while [ [ ${ arr[i] } -le $base && $i -lt $j ] ]
do
let i++
done
arr[j] =${ arr[i] }
arr[i] =$base
quick_f $1 $[i-1]
quick_f $[i+1] $2
}
quick_f 0 ${
echo ${ arr[ * ] }
排序算法之插入排序
算法介绍
插入排序就是提取一个数字后,对已排序的数字从前往后一次比较选择合适的位置插入。这种算法的优点就是任意一个数字可能不需要对比所有的数字就可以找到合适的位置,当然最差的情况也有可能需要对比所有的数字之后才能够确定合适的位置。通常我们默认第一个数字已经排序,然后提取下一个数字,拿这个数字从后往前跟已经排序的数字反复逐一比较,知道该数字找到合适的位置进行插入。最终得到一个有序的序列。
脚本演示
for x in `seq 5`
do
read - p "请输入${x}个随机整数:" num
arr[ $x ] =$num
done
for ( ( i=2; i<=5; i++ ) )
do
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[@]}"
排序算法之计数排序
算法介绍
前三种算法中无论都是基于数字比较进行排序的,而计数排序是不需要进行比较进行排序的。计数排序的核心思想就是多创建一个数组,用于统计待排序数组中每个元素出现的次数。
脚本演示
arr=( 3 2 1 4 5 8 9 7 6 3 3 5 7 1 4 6 2 9)
max=${ arr[ 0] }
for i in `seq $[ ${
do
[ ${ arr[i] } -gt $max ] && max=${ arr[i] }
done
for i in `seq 0 $max `
do
count[i] =0
done
for i in `seq 0 $[ ${
do
let count[ ${ arr[i] } ] ++
done
for i in `seq 0 $[ ${
do
for j in `seq ${ count[i] } `
do
echo - n "$i "
done
done
echo