1. 程式人生 > 其它 >shell 裡陣列排序:氣泡排序,直接排序,反轉排序

shell 裡陣列排序:氣泡排序,直接排序,反轉排序

陣列排序



一 氣泡排序



類似於氣泡上湧的動作,會將資料在陣列中從小到大或者從大到小不斷的向前移動。

基本思想

氣泡排序的基本思想是對比相鄰的兩個元素值,如果滿足條件就交換元素值,把較小的元素移動到陣列前面,把大的元素移動到陣列後面(也就是交換兩個元素的位置),這樣較小的元素就像氣泡一樣從底部上升到頂部。



演算法思路

冒泡演算法有雙層迴圈實現,其中外部迴圈用於控制排序的輪數,一般為要排序的陣列長度減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[@]}"