shell-------排序

Posted 噫噫噫呀呀呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell-------排序相关的知识,希望对你有一定的参考价值。

一、冒泡排序

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

基本思想:

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

算法思路:

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

#arr=(8 5 9 3 4)
read -p "请输入一个数组:" arry

#列表转数组,获取数组长度
arr=($arry)
length=${#arr[@]}

#定义比较轮数,长度-1,比如五个数,比较四轮即可
for ((i=1; i<$length; i++))
do
        #确定内次比较的次数,随着i的增大而降低,因为每轮比较后,最大/小的数已经在末尾了
        for((j=0; j<$length-$i; j++))
        do
                #获取每次用于比较的第一个、第二个数
                first=${arr[$j]}
                k=$[$j+1]
                second=${arr[$k]}
                #比较,如果前一个比后一个数大,则替换,如果是 if [ $first -lt $second ];then,则从大到小排序
                if [ $first -gt $second ];then
                        tem=${arr[$j]}
                        arr[$j]=${arr[$[$j+1]]}
                        arr[$[$j+1]]=$tem
                fi

        done
done

echo "从小到大排序为:"${arr[@]}

在这里插入图片描述
可以用函数实现,先讲输入的列表传入函数,函数再从列表转为数组

#冒泡排序函数
function bubblesort(){

#列表转数组,获取数组长度
arr=($@)
length=${#arr[@]}

#定义比较轮数,长度-1,比如五个数,比较四轮即可
for ((i=1; i<$length; i++))
do
	#确定内次比较的次数,随着i的增大而降低,因为每轮比较后,最大/小的数已经在末尾了
	for((j=0; j<$length-$i; j++))
	do
		#获取每次用于比较的第一个、第二个数
		first=${arr[$j]}
		k=$[$j+1]
		second=${arr[$k]}
		#比较,如果前一个比后一个数大,则替换,如果是 if [ $first -lt $second ];then,则从大到小排序
		if [ $first -gt $second ];then
			tem=${arr[$j]}
			arr[$j]=${arr[$[$j+1]]}
			arr[$[$j+1]]=$tem
		fi		
	done
done

echo ${arr[@]}
}

################## main ###############
#arr=(8 5 9 3 4)
read -p "请输入一个数组:" arry
bubble_result=`bubblesort $arry`
echo "从小到大重新排序后为:"${bubble_result[@]}

二、直接选择排序

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

基本思想:

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

首先记录第一个元素的下标为 index,与下一个元素进行比较,如果下一个元素大于当前i ndex元素的值,就把大的元素的下标给 index,然后 index 继续与下一个元素进行比较,继续判断,直到元素都判断完毕。此时 下标为 index 的就是最大的元素,并放到了最后的位置上。

#直接选择排序函数
function selectsort(){
	#列表转换成数组
	arr=($@)
	length=${#arr[@]}
	
	for((i=1; i<$length; i++))       #定义排序轮训次数,比如五个数只要排序四趟
	do
		index=0
		#确定当前排序 实际最大元素的下标,从第二个元素开始比较,每次都比上次少比一次
		for((j=1; j<=length-i; j++))
		do
			if [ ${arr[$j]} -gt ${arr[$index]} ];then     #如果是从大到小,用 -lt
				index=$j	#如果下一个比当前index大,就把大的值给index
			fi
		done
		#遍历完成,此时下标为index的 就是当前最大的元素
		#把当前比出来的index元素的值 和当前轮循的最后一个元素进行替换
		k=$[$length-$i]
		tmp=${arr[$k]}
		arr[$k]=${arr[$index]}
		arr[$index]=$tmp
	done
	#别忘了返回数组
	echo ${arr[@]}
}

########## mian ##########
read -p "请输入一个数组:" arry
#将列表传给选择排序函数,并获取返回的数组值
select_rest=`selectsort $arry`
echo "选择排序后的数组为:"${select_rest[@]}

在这里插入图片描述

三、反转排序

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

基本思想:

把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换,如果是奇数,中间的不动。

#数组反转函数
function reversal(){
        arr=($@)
        length=${#arr[@]}
        for((i=0; i<$length/2; i++))
        do
                #第一个与倒数第一个替换,第二个与倒数第二个替换
                tmp=${arr[$i]}
                arr[$i]=${arr[$length-1-i]}
                arr[$length-1-i]=$tmp
        done
        echo ${arr[@]}
}

#############main##########
read -p "请输入一个数组:" arry
result=`reversal $arry`
echo "反转后的数组为:"${result[@]}

在这里插入图片描述

四、希尔排序

算法描述:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
按增量序列个数k,对序列进行k 趟排序;
每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
 希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。

java 代码
function shellSort(arr) {
    varlen = arr.length;
    for(vargap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) {
        // 注意:这里和动图演示的不一样,动图是分组执行,实际操作是多个分组交替执行
        for(vari = gap; i < len; i++) {
            varj = i;
            varcurrent = arr[i];
            while(j - gap >= 0 && current < arr[j - gap]) {
                 arr[j] = arr[j - gap];
                 j = j - gap;
            }
            arr[j] = current;
        }
    }
    returnarr;
}

arr[]={6 5 2 1 8 4}
shellSort(arr)

array=(7 6 8 3 1 5 2 4)
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[*]}

在这里插入图片描述

以上是关于shell-------排序的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

PHP希尔(Shell)排序算法的实现(代码详解)

用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]

shell 脚本 片段

vue2.0 代码功能片段

nodejs常用代码片段