從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.1 氣泡排序 - 用 turtle 呈現演算法之執行動作

47 篇文章 1 订阅
33 篇文章 1 订阅

將排序過程, 以海龜移動呈現, 讓學生可以了解演算法的執行過程, 算是用海龜繪圖, 實現演算法視覺化.


“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:
作法就是,

  1. 依序從數列頭到尾(例如, 從左至右), 對每對相鄰的兩個數字
    ( 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),,,,,(kn1,kn)
    1.1 做比較,
    1.2. 然後置換 (如果希望由小排到大, 當左邊較大, 就相鄰的兩個數字置換, 否則就不做任何動作,
    如果希望由大排到小, 當左邊較小, 就置換, 否則就不做任何動作,)
  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()

快速排序 quick sort

合併排序 merge sort

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值