• Python Chapter 10: 列表 Part3


    10.10 查找列表

    线性查找

    线性查找顺序地将关键字key与列表中的每一个元素进行比较,直到找到某个匹配元素时返回其下标,亦或在找不到时返回-1。代码如下:

    # The function for finding a key in a list
    def linearSearch(lst, key):
        for i in range(len(lst)):
            if lst[i] == key:
                return i
    
        return -1
    

    若关键字存在,线性查找在找到关键字前平均需要查找一半的元素,其运行时间与列表中的元素个数成正比(时间复杂度为O(n)?)。这样的效率十分低下。

    二分查找

    在保证关键字是升序排序的基础上,使用二分查找效率很高。其核心在于若关键字比中间的元素大,则仅在中间元素右边寻找,即更新low = mid + 1;若关键字比中间元素小,则仅在中间元素左边寻找,所以更新high = mid - 1;若关键字与中间元素一样大,则找到结果mid。不断循环,若最后有high > mid,则表示找不到关键字元素,则返回-low-1标记关键字应当被放置的位置。代码如下:

    # Use binary search to find key in the list
    def binarySearch(lst, key):
        low = 0
        high = len(lst) - 1
    
        while high >= low:
            mid = (low + high) // 2
            if key < lst[mid]:
                high = mid - 1
            elif key == lst[mid]:
                return mid
            else:
                low = mid + 1
    
        return -low - 1
    

    此算法的时间复杂度为O(logn),比起线性查找高效很多,但前提是保证列表中的元素已经有序。


    10.11 排序列表

    选择排序

    选择排序的核心思想是,在每一次循环中找列表中最小元素与当前的第一个元素交换位置,然后再对剩余列表往复此操作,从而达到使列表中元素升序排列的目的。代码如下:

    # The function for sorting elements in ascending order
    def selectionSort(lst):
        for i in range(len(lst)-1):
            currentMin = lst[i]
            currentMinIndex = i
    
            for j in range(i + 1, len(lst)):
                if lst[j] < currentMin:
                    currentMin = lst[j]
                    currentMinIndex = j
    
            if currentMinIndex != i:
                lst[currentMinIndex] = lst[i]
                lst[i] = currentMin
    

    选择排序的平均时间复杂度为O(n2)

    插入排序

    插入排序的核心思想是,在每一次循环中将一个新的元素插入到已经排好序的列表中,再对剩余元素往复此操作,从而达到使列表中元素升序排列的目的。代码如下:

    # The function for sorting elements in ascending order
    def insertionSort(lst):
        for i in range(1, len(lst)):
            currentElement = lst[i]
            k = i - 1
            while k >= 0 and lst[k] > currentElement:
                lst[k+1] = lst[k]
                k -= 1
            lst[k+1] = currentElement
    

    此算法的时间复杂度亦为O(n2),但其并不是每次都几乎遍历整个列表,因此在常数上会比选择排序略小。
    排序的算法还有冒泡排序、快速排序、堆排序等等,这里仅举例实现。


    10.12 实例学习:弹球

    在屏幕上使一系列弹球运动,并通过按钮使增加一个弹球或减少一个弹球,弹球以列表的形式储存,代码如下:

    from tkinter import *
    from random import randint
    
    def getRandomColor():
        color = "#"
        for j in range(6):
            color += toHexChar(randint(0,15))
        return color
    
    def toHexChar(hexValue):
        if 0 <= hexValue <= 9:
            return chr(hexValue + ord('0'))
        else:
            return chr(hexValue + ord('A') - 10)
    
    class Ball:
        def __init__(self):
            self.x = 0
            self.y = 0
            self.dx = 2
            self.dy = 2
            self.radius = 3
            self.color = getRandomColor()
    
    class BounceBalls:
        def __init__(self):
            self.ballList = []
    
            window = Tk()
            window.title("Bouncing Balls")
    
            self.width = 350
            self.height = 150
            self.canvas = Canvas(window, bg = "white", width = self.width, height = self.height)
            self.canvas.pack()
    
            frame = Frame(window)
            frame.pack()
            btStop = Button(frame, text = "Stop", command = self.stop)
            btStop.pack(side = LEFT)
            btResume = Button(frame, text = "Resume", command = self.resume)
            btResume.pack(side = LEFT)
            btAdd = Button(frame, text = "+", command = self.add)
            btAdd.pack(side = LEFT)
            btRemove = Button(frame, text = "-", command = self.remove)
            btRemove.pack(side = LEFT)
    
            self.sleepTime = 100
            self.isStopped = False
            self.animate()
    
            window.mainloop()
    
        def stop(self):
            self.isStopped = True
    
        def resume(self):
            self.isStopped = False
            self.animate()
    
        def add(self):
            self.ballList.append(Ball())
    
        def remove(self):
            self.ballList.pop()
    
        def animate(self):
            while not self.isStopped:
                self.canvas.after(self.sleepTime)
                self.canvas.update()
                self.canvas.delete("ball")
    
                for ball in self.ballList:
                    self.redisplayBall(ball)
    
        def redisplayBall(self, ball):
            if ball.x > self.width or ball.x < 0:
                ball.dx = -ball.dx
    
            if ball.y > self.height or ball.y < 0:
                ball.dy = -ball.dy
    
            ball.x += ball.dx
            ball.y += ball.dy
            self.canvas.create_oval(ball.x-ball.radius, ball.y - ball.radius, ball.x + ball.radius, ball.y + ball.radius, fill = ball.color, tags = "ball")
    
    BounceBalls()
    

  • 相关阅读:
    Kafka发送到分区的message是否是负载均衡的?
    SpringCloud使用Feign出现java.lang.ClassNotFoundException: org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory异常
    JDBC Mysql 驱动连接异常
    Mysql启动失败解决方案
    前段时间在微信公众号写的文章
    Java线程wait和sleep的区别
    nginx配置反向代理
    分布式锁的几种实现方式
    java四种修饰符的限制范围
    传值&传值引用
  • 原文地址:https://www.cnblogs.com/fsbblogs/p/9742280.html
Copyright © 2020-2023  润新知