shell 裡陣列排序:氣泡排序,直接排序,反轉排序
阿新 • • 發佈:2021-07-21
陣列排序
一 氣泡排序
類似於氣泡上湧的動作,會將資料在陣列中從小到大或者從大到小不斷的向前移動。
基本思想:
氣泡排序的基本思想是對比相鄰的兩個元素值,如果滿足條件就交換元素值,把較小的元素移動到陣列前面,把大的元素移動到陣列後面(也就是交換兩個元素的位置),這樣較小的元素就像氣泡一樣從底部上升到頂部。
演算法思路
冒泡演算法有雙層迴圈實現,其中外部迴圈用於控制排序的輪數,一般為要排序的陣列長度減1,因為最後只剩下一個數組元素,所以不需要對比,同時陣列已經完成排序了。內部迴圈主要用於對比陣列中每個相鄰元素的大小,以確定是否交換位置,對比和交換次數誰輪數而減少。
第一輪排序確定了最大的數。後面依次類推,第二輪確定第二大的數....第五輪確定倒數第五大的數。剩下最後一個數不用排序
#!/bin/bash arr=(20 60 40 30 50 10) echo "原始陣列的順序為: ${arr[@]}" #獲取陣列的長度 length=${#arr[@]} #外層迴圈是用來定義比較的輪數。輪數為陣列的長度減1,從1開始 for ((a=1; a<$length; a++)) do #因為第一輪比較後,確立了最後一個數,第二輪比較後,確定了倒數第二個數...... #用於確鄰比較相鄰元素的位置,較大的往後放,並且每輪比較的最後一個元素下標要遞減 #這裡使用變數b 代表左邊比較元素的下標範圍 #b<$length-$a ,是確定當前輪數比較的次數,第一輪從0到$length-1,第二輪從0到$length-2,.....。 如果有6個數,就是,第一輪比較5次,第二輪比較4次.... for (( b=0; b<$length-$a; b++)) do #定義左邊比較的元素的值 left=${arr[$b]} #定義右邊比較的元素的值 c=$[$b +1 ] right=${arr[$c]} #如果左邊的元素的值比右邊元素的值大,就互換元素的位置 if [ $left -gt $right ];then #把左邊元素的值儲存到臨時變數tmp中 tmp=$left #把右邊元素的值賦給左邊的元素 arr[$b]=$right #再把儲存再臨時變數tmp 中的值賦給右邊的元素 arr[$c]=$tmp fi done done echo "排序後的陣列的順序為: ${arr[@]}"
二:直接排序
直接選擇排序
與氣泡排序相比,直接選擇排序的交換次數更少,所以速度會快些。
基本思想:
將指定排序位置與其它陣列元素分別對比,如果滿足條件就交換元素值,注意這裡區別氣泡排序,不是交換相鄰元素,而是把滿足條件的元素與指定的排序位置交換(如從最後一個元素開始排序) ,這樣排序好的位置逐漸擴大,最後整個陣列都成為已排序好的格式。
#!/bin/bash arr=(20 50 40 30 60 10) echo "原始陣列的順序為: ${arr[@]}" length=${#arr[@]} for ((a=1; a<$length; a++)) do #先假設下標為0的元素的值最大 index=0 #通過比較獲取擁有最大值的元素的下標(或者說索引)index for ((b=1; b<=$length-$a; b++)) do left=${arr[$index]} right=${arr[$b]} if [ $right -gt $left ];then index=$b fi done #把擁有最大值的元素和當前輪次的最後一個元素的值進行交換 last=$[$length -$a] tmp=${arr[$last]} arr[$last]=${arr[$index]} arr[$index]=$tmp done echo "排序後的陣列順序為: ${arr[*]}"
三:反轉排序
反轉排序以相反的順序把原有陣列的內容重新排序。
基本思想:
把陣列最後一個元素與第一個元素替換,倒數第二個元素與第二個元素替換,以此類推,直到把所有陣列元素反轉替換。
#!/bin/bash
arr=(1 2 3 4 5 6 7)
echo "原始陣列排序順序為:${arr[@]}"
length=${#arr[@]}
#因為是兩兩比較,所以除以2取商
for ((a=0; a<$length/2; a++))
do
tmp=${arr[$a]}
arr[$a]=${arr[$length-$a-1]}
arr[$length-$a-1]=$tmp
done
echo "反轉排序後的陣列順序為: ${arr[@]}"