LDP/LDP/guide/docbook/abs-guide/bubble.sh

98 lines
3.1 KiB
Bash
Raw Permalink Normal View History

2001-07-10 14:25:50 +00:00
#!/bin/bash
2001-09-04 13:27:31 +00:00
# bubble.sh: Bubble sort, of sorts.
2001-07-10 14:25:50 +00:00
# Recall the algorithm for a bubble sort. In this particular version...
2002-04-01 16:04:17 +00:00
# With each successive pass through the array to be sorted,
#+ compare two adjacent elements, and swap them if out of order.
# At the end of the first pass, the "heaviest" element has sunk to bottom.
# At the end of the second pass, the next "heaviest" one has sunk next to bottom.
# And so forth.
# This means that each successive pass needs to traverse less of the array.
# You will therefore notice a speeding up in the printing of the later passes.
2001-07-10 14:25:50 +00:00
exchange()
{
# Swaps two members of the array.
2002-04-01 16:04:17 +00:00
local temp=${Countries[$1]} # Temporary storage
#+ for element getting swapped out.
2001-07-10 14:25:50 +00:00
Countries[$1]=${Countries[$2]}
Countries[$2]=$temp
return
}
2002-04-01 16:04:17 +00:00
declare -a Countries # Declare array,
#+ optional here since it's initialized below.
2001-07-10 14:25:50 +00:00
2002-06-03 14:35:48 +00:00
# Is it permissable to split an array variable over multiple lines
#+ using an escape (\)?
# Yes.
Countries=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria \
Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England \
Israel Peru Canada Oman Denmark Wales France Kenya \
Xanadu Qatar Liechtenstein Hungary)
2002-04-01 16:04:17 +00:00
# "Xanadu" is the mythical place where, according to Coleridge,
#+ Kubla Khan did a pleasure dome decree.
2001-07-10 14:25:50 +00:00
2002-06-03 14:35:48 +00:00
2001-09-04 13:27:31 +00:00
clear # Clear the screen to start with.
2001-07-10 14:25:50 +00:00
echo "0: ${Countries[*]}" # List entire array at pass 0.
number_of_elements=${#Countries[@]}
let "comparisons = $number_of_elements - 1"
count=1 # Pass number.
2001-09-04 13:27:31 +00:00
while [ "$comparisons" -gt 0 ] # Beginning of outer loop
2001-07-10 14:25:50 +00:00
do
index=0 # Reset index to start of array after each pass.
2001-09-04 13:27:31 +00:00
while [ "$index" -lt "$comparisons" ] # Beginning of inner loop
2001-07-10 14:25:50 +00:00
do
if [ ${Countries[$index]} \> ${Countries[`expr $index + 1`]} ]
2002-04-01 16:04:17 +00:00
# If out of order...
# Recalling that \> is ASCII comparison operator
#+ within single brackets.
2001-09-04 13:27:31 +00:00
2002-04-01 16:04:17 +00:00
# if [[ ${Countries[$index]} > ${Countries[`expr $index + 1`]} ]]
#+ also works.
2001-07-10 14:25:50 +00:00
then
exchange $index `expr $index + 1` # Swap.
fi
2006-05-19 16:11:49 +00:00
let "index += 1" # Or, index+=1 on Bash, ver. 3.1 or newer.
2001-07-10 14:25:50 +00:00
done # End of inner loop
2004-02-16 17:21:02 +00:00
# ----------------------------------------------------------------------
# Paulo Marcel Coelho Aragao suggests for-loops as a simpler altenative.
#
2006-12-20 21:11:55 +00:00
# for (( last = $number_of_elements - 1 ; last > 0 ; last-- ))
## Fix by C.Y. Hunt ^ (Thanks!)
2004-02-16 17:21:02 +00:00
# do
# for (( i = 0 ; i < last ; i++ ))
2004-02-16 17:21:02 +00:00
# do
# [[ "${Countries[$i]}" > "${Countries[$((i+1))]}" ]] \
# && exchange $i $((i+1))
2004-02-16 17:21:02 +00:00
# done
# done
# ----------------------------------------------------------------------
2001-07-10 14:25:50 +00:00
2002-04-01 16:04:17 +00:00
let "comparisons -= 1" # Since "heaviest" element bubbles to bottom,
#+ we need do one less comparison each pass.
2001-07-10 14:25:50 +00:00
echo
2001-09-04 13:27:31 +00:00
echo "$count: ${Countries[@]}" # Print resultant array at end of each pass.
2001-07-10 14:25:50 +00:00
echo
2001-09-04 13:27:31 +00:00
let "count += 1" # Increment pass count.
2001-07-10 14:25:50 +00:00
2001-09-04 13:27:31 +00:00
done # End of outer loop
2002-04-01 16:04:17 +00:00
# All done.
2001-07-10 14:25:50 +00:00
exit 0