將排序過程, 以海龜移動呈現, 讓學生可以了解演算法的執行過程, 算是用海龜繪圖, 實現演算法視覺化.
“Talk is cheap. Show me the code.”
― Linus Torvalds
老子第41章
上德若谷
大白若辱
大方無隅
大器晚成
大音希聲
大象無形
道隱無名
拳打千遍, 身法自然
“There’s no shortage of remarkable ideas, what’s missing is the will to execute them.” – Seth Godin
「很棒的點子永遠不會匱乏,然而缺少的是執行點子的意志力。」—賽斯.高汀
註: 以下之方法, 主要參考自 官網 IDLE 自帶的 turtle demo 裡 sorting_animation, 那個 demo 的原始碼的做法,
此demo 呈現三種排序: insertion sort 插入排序, selection sort 選擇排序, quick sort 快速排序,
特別是參考, demo 將長條形下方切齊之程式碼
(每個長條代表一個數字, 長度代表該數字之大小, 下方切齊較能比對哪個數字較大, 哪個數字較小), 節省了自己重頭設計的時間,
非常感謝製作 python turtle demo 的義工群!
本系列文章之連結
-
從turtle海龜動畫學習Python-高中彈性課程1 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 2 安裝 Python, 線上執行 Python link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 4 烏龜開始畫圖 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 5 用函數封裝重複性指令-呼叫函數令烏龜畫正 n 邊形 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 6 畫多重旋轉圓,螺旋正方形 link
-
從turtle海龜動畫 學習 Python - 7 遞歸 recursive - 高中彈性課程系列 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 8 碎形 (分形 fractal) link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 8.1 碎形 L-system link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 9 Python 物件導向介紹 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 9.1 Python 物件導向的練習 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 10 藝術畫 自定義海龜形狀 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 10.1 藝術畫 python繪製天然雪花結晶 https://blog.csdn.net/m0_47985483/article/details/122262036 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 10.2 藝術畫 Python 製作生成式藝術 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.1 氣泡排序 - 用 turtle 呈現演算法之執行動作 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.2 maze 迷宮 - 用 turtle 呈現演算法之執行動作 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.3 連分數演算法與轉轉相除法- 用 turtle 呈現演算法之執行動作 link
-
從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.4 最短路徑 Dijkstra- 用 turtle 呈現演算法之執行動作 link
文章目录
氣泡排序 bubble sort
排序算法至少有十多種, 氣泡排序是較直覺簡單的排序算法,
假設給定之數列有 n個數,
(
k
1
,
k
2
,
k
3
,
k
4
,
k
5
,
,
,
,
,
,
k
n
)
(k_1,k_2,k_3,k_4,k_5,,,,,,k_n)
(k1,k2,k3,k4,k5,,,,,,kn)
它的複雜度是
O
(
n
2
)
O(n^2)
O(n2).
Bubble Sorting Algorithm:
作法就是,
- 依序從數列頭到尾(例如, 從左至右), 對每對相鄰的兩個數字
( k 1 , k 2 ) , ( k 2 , k 3 ) , ( k 3 , k 4 ) , , , , , ( k n − 1 , k n ) (k_1,k_2), (k_2,k_3),(k_3,k_4),,,,,(k_{n-1},k_n) (k1,k2),(k2,k3),(k3,k4),,,,,(kn−1,kn)
1.1 做比較,
1.2. 然後置換 (如果希望由小排到大, 當左邊較大, 就相鄰的兩個數字置換, 否則就不做任何動作,
如果希望由大排到小, 當左邊較小, 就置換, 否則就不做任何動作,) - 以上動作叫做一輪, 如此重複 n-1輪
Ex; 說明它的複雜度是 O ( n 2 ) O(n^2) O(n2).
先練習只有文字輸出的氣泡排序
# Bubble sorting output in console
# By Prof. P-J Lai MATH NKNU 20210415
List = [ 9,3,5,15,7,6,10]
sizeList = len(List)
for i in range(sizeList-1):
for j in range(sizeList-1):
if List[j] > List[j+1]:
List[j], List[j+1] = List[j+1], List[j]
print(List)
執行結果
>>>
=== RESTART: C:/Users/user/Desktop/bubbleSort_console.py ===
[3, 5, 6, 7, 9, 10, 15]
Ex: 可以改成隨機產生一堆數字, 對其排序
Sol:
List 改成如下產生:
size = 10
List = [random.randrange(1,20) for i in range(size)]
下面接著講解,
接著再將排序過程, 以海龜移動呈現, 讓學生可以了解演算法的執行過程, 算是用海龜繪圖, 實現演算法視覺化.
產生一組海龜, 形狀為 square, 調整為長方形
##ref: 參考 turtle_module_demo_sorting_animate
##By P-J Lai MATH NKNU 20210411
##
##turtle_sorting_產生長條_1.py
#小心: size_random_shuffle=random.shuffle(size_random)
# 以上會出錯, random.shuffle(size_random)會直接改掉 size_random
# 不會返回, 故size_random_shuffle會是一個 <class 'NoneType'>
# turtle.bye() 關閉海龜繪圖視窗, 在 Spider較不會出錯
# turtle 是以重心為座標
import turtle
import random, time
size = 10
T = turtle.Turtle()
T.shape('square')
T.turtlesize(size*1.5, 1.5, 10)
T.color('yellow','black')
#T.fillcolor('yellow')
T_block = []
size_random = [random.randrange(1,15) for i in range(10)]
# 產生一組海龜, 形狀為 square, 調整為長方形
for i in range(10):
T = turtle.Turtle()
T.shape('square')
T.color('yellow','black')
T.turtlesize(size_random[i]*1.5, 1.5, 10)
T_block.append(T)
#size_random_shuffle=random.shuffle(size_random)
# 以上會出錯, random.shuffle(size_random)會直接改掉 size_random
# 不會返回, 故size_random_shuffle會是一個 <class 'NoneType'>
#########################################
# 移動試做
random.shuffle(size_random)
for i in range(10):
T_block[i].fd(size_random[i]*25)
for i in range(1,11):
T_block[i-1].home()
#########################################
time.sleep(1)
for i in range(1,11):
T_block[i-1].fd(i*40)
print(T_block[i-1].pos(),end=', ')
# 參考 demo codes: def push(self, d):,,,# align blocks by the bottom edge
##width, _, _ = d.shapesize()
### align blocks by the bottom edge
##y_offset = width / 2 * 20
##d.sety(self.y + y_offset)
##d.setx(self.x + 34 * len(self))
turtle.mainloop()
# turtle.bye()
每條往上平移, 使下方切齊, 再移到 canvas 正中
##ref: 參考 turtle_module_demo_sorting_animate
##By P-J Lai MATH NKNU 20210413
##
##turtle_sorting_切平_2.py
# 可以單獨抽出 stretch_wid.
# turtle.turtlesize(stretch_wid=None, stretch_len=None, outline=None)
##>>> import turtle
##>>> T = turtle.Turtle()
##>>> T.turtlesize()
##(1.0, 1.0, 1)
##>>> T.turtlesize()[0]
##1.0
# turtle.bye() 關閉海龜繪圖視窗, 在 Spider較不會出錯
import turtle
import random, time
size = 10
TFont = turtle.Turtle()
#T.shape('square')
#T.turtlesize(size*1.5, 1.5, 10)
TFont.color('black','red')
#T.fillcolor('yellow')
T_block = []
size_random = [random.randrange(1,20) for i in range(10)]
print(size_random)
# 產生一組海龜, 形狀為 square, 調整為長方形
for i in range(10):
T = turtle.Turtle()
T.shape('square')
T.color('yellow','black')
T.turtlesize(size_random[i]*1.5, 1.5, 10)
T.penup()
T_block.append(T)
##time.sleep(1)
for i in range(1,11):
T_block[i-1].fd(i*40)
print(T_block[i-1].pos(),end=', ')
# 參考 demo codes: def push(self, d):,,,# align blocks by the bottom edge
##width, _, _ = d.shapesize()
### align blocks by the bottom edge
##y_offset = width / 2 * 20
##d.sety(self.y + y_offset)
##d.setx(self.x + 34 * len(self))
time.sleep(1)
widthList=[]
# 以下是參考 demo 的 codes, 將 長條形的下方, 水平切齊
# 1. 先抽取每個隨機長條形之寬度(長度), 目前turtle是向左, 所以是他的寬度,
for i in range(1,11):
height, _, _ = T_block[i-1].shapesize()
widthList.append(height)
# 2. 每條往上平移, 使下方切齊
y_offsetList=[]
for i in range(1,11):
# turtle.turtlesize(stretch_wid=None, stretch_len=None, outline=None)
# 返回或设置画笔的属性 x/y-拉伸因子和/或轮廓
# 注意, T.turtlesize(size*1.5, 1.5, 10)裡面的值是stretch factor
# 實際長, 可能是要乘 20
y_offsetList.append(widthList[i-1] / 2 *20)
T_block[i-1].sety(y_offsetList[i-1])
# 3. 全部移到 canvas 正中
time.sleep(1)
for i in range(1,11):
T_block[i-1].setpos(-200 + i*40,-200 + y_offsetList[i-1])
# 4. 寫出 "Bubble sorting preparing is down" 的說明
TFont.ht()
TFont.penup()
TFont.setpos(-200,-300)
TFont.write("Bubble sorting preparing is down", move=False, align="left", font=("Arial", 30, "normal"))
turtle.mainloop()
# turtle.bye()
開始 bubble sort
##ref: 參考 turtle_module_demo_sorting_animate
##By P-J Lai MATH NKNU 20210413
##
##turtle_sorting_bubble_3.py
# 可以單獨抽出 stretch_wid.
# turtle.turtlesize(stretch_wid=None, stretch_len=None, outline=None)
##>>> import turtle
##>>> T = turtle.Turtle()
##>>> T.turtlesize()
##(1.0, 1.0, 1)
##>>> T.turtlesize()[0]
##1.0
import turtle
import random, time
size = 7
TFont = turtle.Turtle()
#T.shape('square')
#T.turtlesize(size*1.5, 1.5, 10)
TFont.color('black', 'red')
#T.fillcolor('yellow')
T_block = []
size_random = [random.randrange(1,20) for i in range(10)]
print(size_random)
# 產生一組海龜, 形狀為 square, 調整為長方形
for i in range(size):
T = turtle.Turtle()
T.shape('square')
T.color('yellow','black')
T.turtlesize(size_random[i]*1.5, 1.5, 10)
T.penup()
T.ht()
T_block.append(T)
##time.sleep(1)
#########################################
# 移動試做
for i in range(size):
T_block[i].fd(i*40)
print(T_block[i].pos(),end=', ')
# 參考 demo codes: def push(self, d):,,,# align blocks by the bottom edge
time.sleep(1)
######################################################
# 水平切齊
widthList=[]
# 以下是參考 demo 的 codes, 將 長條形的下方, 水平切齊
# 1. 先抽取每個隨機長條形之寬度(長度), 目前turtle是向左, 所以是他的寬度,
for i in range(size):
height, _, _ = T_block[i].shapesize()
widthList.append(height)
# 每條往上平移, 使下方切齊
y_offsetList=[]
for i in range(size):
y_offsetList.append(widthList[i] / 2 *20)
T_block[i-1].sety(y_offsetList[i])
# 全部移到 canvas 正中
time.sleep(1)
for i in range(size):
T_block[i].setpos(-200 + (i+1)*40,-200 + y_offsetList[i])
T_block[i].st()
###################################################
# bubble sort
# 以下程式碼錯在, widthList[j] 還是用舊的長度資料
##for i in range(3):
## for j in range(size-1):
## if widthList[j] > widthList[j+1]:
## tempX1, tempX2 = T_block[j].xcor(), T_block[j+1].xcor()
## T_block[j].setx(tempX2)
## time.sleep(1)
## T_block[j+1].setx(tempX1)
## T_block[j], T_block[j+1] = T_block[j+1], T_block[j]
## time.sleep(2)
# 可以單獨抽出 stretch_wid.
##>>> T.turtlesize()
##(1.0, 1.0, 1)
##>>> T.turtlesize()[0]
##1.0
for i in range(3):
for j in range(size-1):
if T_block[j].turtlesize()[0] > T_block[j+1].turtlesize()[0]:
tempX1, tempX2 = T_block[j].xcor(), T_block[j+1].xcor()
T_block[j].setx(tempX2)
time.sleep(1)
T_block[j+1].setx(tempX1)
T_block[j], T_block[j+1] = T_block[j+1], T_block[j]
time.sleep(2)
TFont.ht()
TFont.penup()
TFont.setpos(-200,-300)
#TFont.write("Bubble sorting preparing is down", move=False, align="left", font=("Arial", 30, "normal"))
TFont.write("Bubble sorting is down", font=("Arial", 30, "normal"))
#turtle.clearscreen()
#turtle.reset()
turtle.mainloop()
# turtle.bye()