<返回更多

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

2020-08-19    
加入收藏

1 说明:

=====

1.1 冒泡排序:

1.1.1 原理:比较两个相邻的元素,将值大的元素交换至右端。

1.1.2 来源:由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故得名。

1.1.3 是一种最简单直观的排序算法之一。

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

 

1.2 冒泡排序可视化:

1.2.1 Bubble Sort Visualizer。

1.2.2 更能直观了解这种排序。

1.2.3 通过多种方法实现,理解该算法,同时复习Python

1.2.4 python法,采用:matplotlib法、pygame法、turtle法(2d+3d)、opencv法。

1.2.5 代码来源网络,来源已注明,仅供学习,感谢网友,适合收藏。

============

具体代码和讲解

============

2 python法:

========

2.1 matplotlib法

2.1.1 效果图:

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

 

2.1.2 代码来源:

#https://blog.csdn.net/m1090760001/article/details/103217052

2.1.3 代码一:

from matplotlib import pyplot as plt
import random

LIST_SIZE = 10  #10个组bar
PAUSE_TIME = 4 / LIST_SIZE
# 冒泡算法
def bubble_sort(nums):
    for i in range(len(nums) - 1):
        for j in range(len(nums) - i - 1):
            if nums[j] > nums[j + 1]:
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
            plt.cla()  # 清除内容
            plt.bar(range(len(nums)), nums, align='center')
            plt.bar(j, nums[j], color="r", align="center")
            plt.bar(j + 1, nums[j + 1], color="r", align="center")
            plt.pause(PAUSE_TIME)
    plt.show()

if __name__ == "__main__":
    nums = []
    for i in range(LIST_SIZE):
        nums.Append(random.randint(0, 1000))  #随机生成
    bubble_sort(nums)
    print(nums)

2.2 turtle法:

2.2.1 2d-turtle法:

2.2.1.1 来源:

#https://blog.csdn.net/avskya/article/details/82958907

2.2.1.2 效果图:

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

 

2.2.1.3 代码二:

from turtle import *
from random import randint
from time import sleep

class Column(Turtle):
    def __init__(self,x):
        Turtle.__init__(self,shape='square')     
        self.up()                         #抬笔
        r = randint(0,255)
        g = randint(0,255)
        b = randint(0,255)        
        self.fillcolor(r,g,b)
        self.scale = randint(1,38)        # 20 * self.scale 为柱子高度
        self.setx(x)
        self.__half__ = self.screen.window_height()//2 #屏幕的半高
        self.shapesize(self.scale,1)                   #相对于自身坐标系前进的垂直方向放大
        self.sety(0- self.__half__ + 10*self.scale  + 30)  
        
if __name__=="__main__":
    width,height=800,800
    screen = Screen()
    screen.colormode(255)
    screen.setup(width,height)
    screen.title("冒泡排序动态演示")
    screen.delay(0)
    xcors = [x for x in range(40-width//2,width//2-20,40) ]
    columns = [Column(x) for x in xcors ] #生成所有柱子
    length = len(columns)
    while True:
        Flag = False                  #描述是否交换了数据的标志
        for i in range(0,length-1 ):      #由于越往后,越不要排这么多次数了.
            c1 = columns[i]               #代表前面柱子
            c2 = columns[i + 1]           #代表后面柱子
            if c1.scale > c2.scale:       #如果前面的柱子更高,则交换位置
                x1 = c1.xcor()             #保留前面柱子c1的x坐标
                x2 = c2.xcor()             #保留后面柱子c2的x坐标
                columns[i] = c2            #让前面的柱子赋值为后面柱子        
                columns[i+1] = c1          #让后面的柱子赋值为前面柱子
                columns[i].setx(x1)   #交换列表中项目后,重新设置x坐标
                columns[i+1].setx(x2) #交换列表中项目后,重新设置x坐标
                Flag = True
            screen.update()
            sleep(0.1)
            
        length = length - 1
        if  Flag == False:break #如果一次都没有排序,则退出while循环

2.2.2 3d-turtle法:

2.2.2.1 来源:

#https://blog.csdn.net/magicdoubi/article/details/88843825

2.2.2.2 效果图:

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

 

2.2.2.3 代码三:

from turtle import *
from random import *
import time

def bubble_sort(rectangle_list):
    for passnum in range(0, 10 - 1):
        for i in range(0, 10 - passnum - 1, 1):
            if rectangle_list[i].num > rectangle_list[i + 1].num:
                rectangle_list[i].replace(rectangle_list[i + 1])
                time.sleep(0.5)  # 休眠1秒

class Cube():
    def __init__(self, x, y, num, leng=10):
        self.x = x
        self.y = y
        self.num = num
        self.side_len = leng
        self.create_cube()

    def create_side(self):
        fillcolor("#639CD3")
        begin_fill()
        left(170)
        forward(self.side_len)
        right(80)
        forward(20 * self.num)
        right(100)
        forward(self.side_len)
        right(80)
        forward(20 * self.num)
        end_fill()
        setheading(0)  # 恢复向右默认

    def create_top(self):
        fillcolor("#95CEFF")
        penup()
        goto(self.x, self.y + 20 * self.num)
        pendown()
        begin_fill()
        forward(20)
        left(170)
        forward(self.side_len)
        left(10)
        forward(20)
        left(170)
        forward(self.side_len)
        end_fill()
        setheading(0)  # 恢复向右默认

    def create_rectangle(self):
        color("#639CD3")
        penup()
        goto(self.x, self.y)
        pendown()
        #柱的正面颜色
        fillcolor("green")
        begin_fill()
        for x in range(1, 5):
            if x % 2 == 1:
                n = 20
            else:
                n = 20 * self.num
            forward(n)
            left(90)
        end_fill()

    def create_cube(self):
        tracer(False)
        self.create_rectangle()
        self.create_side()
        self.create_top()
        tracer(True)

    def erase_rectangle(self):
        setheading(0)
        color("white")
        penup()
        goto(self.x, self.y)
        pendown()
        fillcolor("white")
        begin_fill()
        for x in range(1, 5):
            if x % 2 == 1:
                n = 20
            else:
                n = 20 * self.num
            forward(n)
            left(90)
        end_fill()

    def erase_side(self):
        fillcolor("white")
        begin_fill()
        left(170)
        forward(self.side_len)
        right(80)
        forward(20 * self.num)
        right(100)
        forward(self.side_len)
        right(80)
        forward(20 * self.num)
        end_fill()
        setheading(0)  # 恢复向右默认

    def erase_top(self):
        fillcolor("white")
        penup()
        goto(self.x, self.y + 20 * self.num)
        pendown()
        begin_fill()
        forward(20)
        left(170)
        forward(self.side_len)
        left(10)
        forward(20)
        left(170)
        forward(self.side_len)
        end_fill()
        setheading(0)  # 恢复向右默认

    def erase_cube(self):
        tracer(False)
        self.erase_rectangle()
        self.erase_side()
        self.erase_top()
        tracer(True)

    def replace(self, n):
        self.erase_cube()
        n.erase_cube()
        self.num, n.num = n.num, self.num
        self.create_cube()
        n.create_cube()

if __name__ == '__main__':
    hideturtle()
    var = list()
    for i in range(0, 10):
        var.append(Cube(35 * i, 0, randint(1, 10)))
    bubble_sort(var)
    done()

2.3 opencv法:

2.3.1 来源:

#https://blog.csdn.net/u011983560/article/details/106195385

2.3.2 效果图:

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

 

2.3.3 代码四:

import numpy as np
import os
import cv2

class Dataseq():
    WHITE = (255,255,255)
    RED = (0,0,255)
    BLACK = (0,0,0)
    YELLOW = (0,127,255)
    
    def __init__(self, data=None,sort_type='figure'):
        self.sort_type=sort_type
        self.interval=400  #原来是5,太小了 
        #注意与data数据最大值和最小值也有关系,与跳跃时间也有关
        self.inter=2
        if data==None:
            print("there are no data to sort!!!")
            os.exit()
        else:
            self.data=data
            self.maxd=max(self.data)  #最大值
            self.mind=min(self.data)  #最小值
        self.getfigure()
        self.Visualize()
        self.sortdata()
    
    def getfigure(self):
        datanum=len(self.data)
        maxd=max(self.data)
        mind=min(self.data)
        self.figure=np.full((500*(maxd-mind)+50, (datanum)*(self.interval+self.inter), 3), 255,dtype=np.uint8)
        for i in range(len(self.data)):
            self.figure[-50-(self.data[i]-mind)*500:,(i)*(self.interval+self.inter):(i)*(self.interval+self.inter)+self.interval]=self.YELLOW
    
    def choice(self, i, j):
        mind=self.mind
        self.figure[-50-(self.data[i]-mind)*500:,(i)*(self.interval+self.inter):(i)*(self.interval+self.inter)+self.interval]=self.BLACK
        self.figure[-50-(self.data[j]-mind)*500:,(j)*(self.interval+self.inter):(j)*(self.interval+self.inter)+self.interval]=self.BLACK
        self.Visualize()
    
    def change(self,i,j):
        mind=self.mind
        self.figure[-50-(self.data[i]-mind)*500:,(i)*(self.interval+self.inter):(i)*(self.interval+self.inter)+self.interval]=self.WHITE
        self.figure[-50-(self.data[j]-mind)*500:,(j)*(self.interval+self.inter):(j)*(self.interval+self.inter)+self.interval]=self.WHITE
        indata=self.data[i]
        self.data[i]=self.data[j]
        self.data[j]=indata
        self.figure[-50-(self.data[i]-mind)*500:,(i)*(self.interval+self.inter):(i)*(self.interval+self.inter)+self.interval]=self.BLACK
        self.figure[-50-(self.data[j]-mind)*500:,(j)*(self.interval+self.inter):(j)*(self.interval+self.inter)+self.interval]=self.BLACK
        self.Visualize()
    
    def Visualize(self):
        figure1=self.figure
        cv2.namedWindow('img',cv2.WINDOW_NORMAL)
        cv2.imshow('img',figure1)
        cv2.waitKey(1000)

    def sortdata(self):
        for di in range(len(self.data)):
            for dj in range(len(self.data)-di-1):
                self.choice(dj,dj+1)
                if self.data[dj]>self.data[dj+1]:
                    self.change(dj,dj+1)
                self.getfigure()

datat=Dataseq([10,20,30,15,25,18],'sort') 
datat.Visualize()   
cv2.destroyAllwindows()

2.4 pygame法:

2.4.1 来源:

#https://github.com/zetaleee/Visualization-algorithm

2.4.2 效果图:

5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

 

2.4.3 代码五:

import pygame
from random import randint

gap = 10                        #竖条的间隔
width = 30                      #竖条的宽度
screenSize = (600, 250)         #显示屏幕的尺寸
barXPosition = []               #竖条在坐标轴的位置
Bars = []                       #竖条对象列表
#生成颜色
class color(object):
    @staticmethod
    def RandomColor():
        r,g,b = randint(0,225),randint(0,255),randint(0,255)
        return (r,g,b)
    @staticmethod
    def CalculateColor(self,num):
        pass

class bar(object):
    def __init__(self, n,num,screen,width = 30):
        self.n = n
        self.locationX = barXPosition[n]
        self.locationY = screenSize[1]-50-num
        self.num = num
        self.color = color.RandomColor()
        self.width = width
        self.font = pygame.font.Font(None, 20)
        self.screen = screen
    #绘制竖条及其上方的数字
    def BarDraw(self):
        pygame.draw.rect(self.screen, self.color,
                         ((self.locationX,self.locationY), (self.width, self.num)))
        self.txt = self.font.render("{}".format(self.num), True, self.color)
        self.screen.blit(self.txt, (self.locationX+5,self.locationY-20))
    #移动竖条,flag是用于判断移动方向 True向右 False向左
    def move(self,flag):
        pace = 2    #移动的步长
        #消除移动前的竖条
        pygame.draw.rect(self.screen, (255, 255, 235),
                         ((self.locationX, self.locationY), (self.width, self.num)))
        if flag:
            self.locationX += pace
        else:
            self.locationX -= pace
        # 绘制移动后的竖条
        pygame.draw.rect(self.screen, self.color,
                         ((self.locationX , self.locationY), (self.width, self.num)))
    #交换相邻两个竖条
    def ChangeLocation(self,otherBall):
        #清除当前位置图像与文字
        pygame.draw.rect(self.screen, (255, 255, 235),
                         ((self.locationX, self.locationY-20), (self.width, self.num+20)))
        pygame.draw.rect(otherBall.screen, (255, 255, 235),
                         ((otherBall.locationX, otherBall.locationY - 20), (otherBall.width, otherBall.num + 20)))
        #竖条移动的动画
        for n in range(20):
            self.move(True)
            otherBall.move(False)
            pygame.time.delay(40)
            pygame.display.flip()
        #移动后,重新写上竖条对应的数字
        self.screen.blit(self.txt, (self.locationX + 5, self.locationY - 20))
        otherBall.screen.blit(otherBall.txt, (otherBall.locationX + 5, otherBall.locationY - 20))
        #交换竖条对象在列表的位置,同时交换排位数字
        Bars[self.n],Bars[otherBall.n] =  Bars[otherBall.n],Bars[self.n]
        self.n,otherBall.n = otherBall.n,self.n
        pygame.display.flip()
        pygame.time.delay(200)      #此延时控制排序动画的快慢
#冒泡排序
def algorithm(nums):
    for i in range(len(nums) - 1):
        for j in range(len(nums) - 1 - i):
            if nums[j] > nums[j + 1]:
                Bars[j].ChangeLocation(Bars[j + 1])
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
#计算十二个竖条在轴上的位置
def barX(gap,width,barXs):
        for n in range(12):
            barX = 50 + gap + (gap + width) * n
            barXs.append(barX)

def main():
    nums = []
    pygame.init()
    screen = pygame.display.set_mode(screenSize)
    pygame.display.set_caption("算法")                #标题
    screen.fill((255, 255, 235))                     #背景色
    barX(gap,width,barXPosition)                     #计算bar位置并存于barXs
    pygame.draw.aaline(screen,(0,255,0),(50,screenSize[1]-50),
                       (screenSize[0]-50,screenSize[1]-50))  #绘制坐标轴
    pygame.display.flip()
    #生成十二个竖条并绘制
    for n in range(12):
        num = randint(20,160)
        tempBar = bar(n,num,screen)
        tempBar.BarDraw()
        nums.append(num)
        Bars.append(tempBar)
        pygame.time.delay(50)  #此处延时是为了开始时演示动画效果
        pygame.display.flip()
    algorithm(nums)  #排序
    #等待关闭窗口事件
    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

if __name__ == "__main__":
    main()

===自己整理并分享出来===

喜欢的人,请点赞、关注、评论、转发和收藏。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>