【CS】Python算法-实现篇

目录

  • 前置知识
文章:  Python算法-概念篇
  • 排序
  1. 冒泡排序
  2. 选择排序
  3. 插入排序
  4. 谢尔排序
  5. 归并排序
  6. 快速排序
  • 查找
  1. 顺序查找(已排序的表/未排序的表)
  2. 二分查找
  • 常见基本算法
  1. 最大公约数
  2. 斐波那契数列
  3. 判断素数
  4. 变位词
  1. 括号匹配
  2. 前中后缀表达式
  3. 进制转换
  • 队列
  1. 热土豆问题(约瑟夫问题)
  2. 回文序列
  • 递归
  1. 数列求和
  2. 汉诺塔
  3. 探索迷宫
  4. 递归画树
  5. 递归画螺旋曲线
  6. 递归画三角形
  • 优化/动态规划
  1. 找零兑换
  2. 博物馆大盗
  1. 表达式解析/求值/恢复原表达式
  1. 词梯问题
  2. 骑士周游/Warnsdorff改进
  3. 拓扑排序
  4. 强连通分支
  5. 最短路径
  6. 最小生成树
  7. 图深度遍历
  • 其他
  1. 旅行商问题

https://github.com/YizheZhang-Ervin/Algorithms_Python_V2​github.com/YizheZhang-Ervin/Algorithms_Python_V2​编辑

1.排序

  • 冒泡排序
def bubbleSort(alist):
    for passnum in range(len(alist) - 1, 0, -1):
        # 比较还未排序的余下的列表
        for i in range(passnum):
            # 整个列表所有数比较,最大的放最后
            if alist[i] > alist[i + 1]:
                temp = alist[i]
                alist[i] = alist[i + 1]
                alist[i + 1] = temp


def shortBubbleSort(alist):
    exchanges = True
    passnum = len(alist) - 1

    while passnum > 0 and exchanges:
        exchanges = False
        # 比较还未排序的余下的列表
        for i in range(passnum):
            # 整个列表所有数比较,最大的放最后
            if alist[i] > alist[i + 1]:
                # 如果所有数都<后一个,则说明已有序,不用继续比较
                exchanges = True
                temp = alist[i]
                alist[i] = alist[i + 1]
                alist[i + 1] = temp
        passnum = passnum - 1
  • 选择排序
def selectionSort(alist):
    for fillslot in range(len(alist) - 1, 0, -1):
        positionOfMax = 0
        # 未排序的全表比较,选出最大的记录下索引
        for location in range(1, fillslot + 1):
            if alist[location] > alist[positionOfMax]:
                positionOfMax = location
        # 把最大的数和当前未排序部分的最后一个数进行交换
        temp = alist[fillslot]
        alist[fillslot] = alist[positionOfMax]
        alist[positionOfMax] = temp
  • 插入排序
def insertionSort(alist):
    # 循环逐步扩大有序表
    for index in range(1, len(alist)):
        currentvalue = alist[index]
        position = index
        # 一段范围内,当前值<前面某值(向前对比),前面最大的某值最终赋给当前值的位置,并逐步扩大有序的范围
        while position > 0 and alist[position - 1] > currentvalue:
            alist[position] = alist[position - 1]
            position = position - 1
        # 最大值赋给当前值位置后,当前值放到最大值的位置
        alist[position] = currentvalue
  • 谢尔排序
def shellSort(alist):
    sublistcount = len(alist) // 2
    while sublistcount > 0:
        # 间隔划分为子列表,对每个子列表分别插入排序
        for startposition in range(sublistcount):
            gapInsertionSort(alist, startposition, sublistcount)
        print("After increments of size", sublistcount, "The list is", alist)
        sublistcount = sublistcount // 2


def gapInsertionSort(alist, start, gap):
    for i in range(start + gap, len(alist), gap):
        currentvalue = alist[i]
        position = i
        # 向前比较
        while position >= gap and alist[position - gap] > currentvalue:
            alist[position] = alist[position - gap]
            position = position - gap
        alist[position] = currentvalue
  • 归并排序
def mergeSort(alist):
    print("Splitting ", alist)
    if len(alist) > 1:
        # 拆分左半右半
        mid = len(alist) // 2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]
        # 递归归并排序
        mergeSort(lefthalf)
        mergeSort(righthalf)

        i, j, k = 0, 0, 0
        # 拉链对比
        while i < len(lefthalf) and j < len(righthalf):
            # 左小,左数加入总表
            if lefthalf[i] < righthalf[j]:
                alist[k] = lefthalf[i]
                i = i + 1
            # 右小,右数加入总表
            else:
                alist[k] = righthalf[j]
                j = j + 1
            # 判断完一次后,总表索引向后移一格
            k = k + 1
        # 右表比完之后,左表还有遗留,逐个加入总表
        while i < len(lefthalf):
            alist[k] = lefthalf[i]
            i = i + 1
            k = k + 1
        # 左表比完之后,右表还有遗留,逐个加入总表
        while j < len(righthalf):
            alist[k] = righthalf[j]
            j = j + 1
            k = k + 1
    print("Merging ", alist)
  • 快速排序
def quickSort(alist):
    quickSortHelper(alist, 0, len(alist) - 1)


def quickSortHelper(alist, first, last):
    if first < last:
        # 右指针
        splitpoint = partition(alist, first, last)
        # 根据中值分两半的左半部分递归
        quickSortHelper(alist, first, splitpoint - 1)
        # 根据中值分两半的右半部分递归
        quickSortHelper(alist, splitpoint + 1, last)


def partition(alist, first, last):
    # 将第一个值设置为中值
    pivotvalue = alist[first]
    # 左指针
    leftmark = first + 1
    # 右指针
    rightmark = last

    done = False
    while not done:
        # 左指针在右指针左边,左指针位置处的值<=中值
        while leftmark <= rightmark and \
                alist[leftmark] <= pivotvalue:
            leftmark = leftmark + 1
        # 左指针在右指针左左边,左指针位置处的值>=中值
        while alist[rightmark] >= pivotvalue and \
                rightmark >= leftmark:
            rightmark = rightmark - 1
        # 左指针在右指针右边
        if rightmark < leftmark:
            done = True
        # 左指针在右指针左左边,左右指针处的值互换
        else:
            temp = alist[leftmark]
            alist[leftmark] = alist[rightmark]
            alist[rightmark] = temp
    # 右指针处的值和中值互换
    temp = alist[first]
    alist[first] = alist[rightmark]
    alist[rightmark] = temp

    return rightmark

2.查找

  • 顺序查找(已排序的表/未排序的表)
def sequentialSearch(alist, item):
    """
    未排序的表
    """
    pos = 0
    found = False
    while pos < len(alist) and not found:
        if alist[pos] == item:
            found = True
        else:
            pos = pos+1
    return found


def orderedSequentialSearch(alist, item):
    """
    已排序的表
    """
    pos = 0
    found = False
    stop = False
    while pos < len(alist) and not found and not stop:
        if alist[pos] == item:
            found = True
        else:
            # 如果列表中某个值直接大于目标值,因为是有序表,说明后面不会再有相等的了,直接跳查找失败
            if alist[pos] > item:
                stop = True
            else:
                pos = pos+1

    return found
  • 二分查找
def binarySearch(alist, item):
    first = 0
    last = len(alist) - 1
    found = False

    while first <= last and not found:
        # 中间值 = (头+尾)/2
        midpoint = (first + last) // 2
        if alist[midpoint] == item:
            found = True
        else:
            # 目标值<中间值,在前部找
            if item < alist[midpoint]:
                last = midpoint - 1
            # 目标值>中间值,在后部找
            else:
                first = midpoint + 1

    return found


def binarySearch2(alist, item):
    """
    递归 二分查找
    """
    if len(alist) == 0:
        return False
    else:
        midpoint = len(alist) // 2
        if alist[midpoint] == item:
            return True
        else:
            # 目标值<中间值,在前部找
            if item < alist[midpoint]:
                return binarySearch2(alist[:midpoint], item)
            # 目标值>中间值,在后部找
            else:
                return binarySearch2(alist[midpoint + 1:], item)

3.常见基本算法

  • 最大公约数
def hcf(x, y):
   # 获取最小值
   if x > y:
       small = y
   else:
       small = x
   for i in range(1,small + 1):
       if((x % i == 0) and (y % i == 0)):
           hcf = i
   return hcf
  • 斐波那契数列
def printFibonacci(n):
    """
    n为数列的数字个数
    斐波那契数列0,1,1,2,3,5,8,13,21...
    f(n)=f(n-1)+f(n-2)
    """
    lis = [0, 1]
    a, b = lis
    for i in range(n - 2):
        a, b = b, a + b
        lis.append(b)
    return lis


def printFibonacci2(n):
    """
    递归斐波那契数列
    """
    def recursion(n):
        if n == 0: return 0
        if n == 1: return 1
        return recursion(n - 1) + recursion(n - 2)

    lis = []
    for i in range(n):
        lis.append(recursion(i))
    return lis
  • 判断素数
def checkPrime(nums):
    """
    从2~sqrt(n)+1判断
    """
    ranges = range(2, int(sqrt(nums) + 1))
    for i in ranges:
        if nums % i == 0:
            return False
    return True


def checkPrime2(nums):
    """
    从2~sqrt(n)判断,只需要判断6x+1,6x+5
    """
    flag = True
    if nums == 2 or nums == 3:
        return flag
    if nums % 6 != 1 and nums % 6 != 5:
        flag = False
        return flag
    for i in range(5, int(sqrt(nums)) + 2, 6):
        if nums % i == 0 or nums % (i + 2) == 0:
            flag = False
            return flag
    return flag
  • 变位词
def checkAnagrams(wordA, wordB):
    """
    变位词
    """
    word_dictA, word_dictB = {}, {}
    for i in wordA:
        word_dictA[i] = word_dictA.get(i, 0) + 1
    for j in wordB:
        word_dictB[j] = word_dictB.get(j, 0) + 1
    return word_dictA == word_dictB

4.栈

  • 括号匹配
# 括号匹配检查
def expressionCheck(exp):
    """
    括号匹配检查,不包含数字符号等
    """
    exp_dict = {'(': ')', '[': ']', '{': '}'}
    s = Stack()
    flag = True
    for i in exp:
        # 如果是左括号
        if i in '([{':
            s.push(i)
        # 如果是右括号
        else:
            # 栈空则说明不匹配
            if s.isEmpty():
                flag = False
                break
            # 栈不空看括号类型是否匹配
            else:
                top = s.pop()
                if not exp_dict[top] == i:
                    flag = False
                    break
    return flag and s.isEmpty()
  • 前中后缀表达式
# 中缀转后缀
def expressionConversion(infixexpr):
    prec = {"*": 3, "/": 3, "+": 2, "-": 2, "(": 1}
    opStack = Stack()
    postfixList = []
    tokenList = infixexpr.split()

    for token in tokenList:
        # 字符数字直接加入list
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            postfixList.append(token)
        # 左括号压入栈
        elif token == '(':
            opStack.push(token)
        # 右括号
        elif token == ')':
            # 弹出栈顶符号
            topToken = opStack.pop()
            # 栈顶非左括号
            while topToken != '(':
                # 栈顶元素加入list
                postfixList.append(topToken)
                # 继续从栈顶拿出元素直到是左括号位置
                topToken = opStack.pop()
        # 运算符号
        else:
            # 栈顶运算符号优先级>当前运算符号,栈顶运算符号出栈并加入list
            while not opStack.isEmpty() and prec[opStack.peek()] >= prec[token]:
                postfixList.append(opStack.pop())
            # 当前运算符号加入栈
            opStack.push(token)
    # 栈不空则把栈剩下的全部加到list中
    while not opStack.isEmpty():
        postfixList.append(opStack.pop())
    return " ".join(postfixList)

# 表达式求值
def expressionEvaluation(postfixExpr):
    operandStack = Stack()
    tokenList = postfixExpr.split()
    for token in tokenList:
        # 数字则压入栈
        if token in "0123456789":
            operandStack.push(int(token))
        # 非数字
        else:
            # 先出栈的是操作数2
            operand2 = operandStack.pop()
            # 后出栈的是操作数1
            operand1 = operandStack.pop()
            # 运算
            result = doMath(token, operand1, operand2)
            # 运算结果压入栈
            operandStack.push(result)
    return operandStack.pop()


def doMath(op, op1, op2):
    if op == "*":
        return op1 * op2
    elif op == "/":
        return op1 / op2
    elif op == "+":
        return op1 + op2
    else:
        return op1 - op2
  • 进制转换
def baseConversion(nums, base):
    """
    迭代版 进制转换:10进制~任意(2-16)进制
    """
    if base not in range(2, 17):
        print('ERROR!Base can only in 2-16')
        return
    digits = '0123456789ABCDEF'
    s = Stack()
    n = nums
    rst = ''
    while n:
        q, r = divmod(n, base)
        # 余数压入栈
        s.push(r)
        # 商继续运算
        n = q
    # 出栈并映射到0~F
    for i in range(s.size()):
        rst += digits[s.pop()]
    return rst


def baseConversion2(nums, base):
    """
        递归版 进制转换:10进制~任意(2-16)进制
    """
    digits = '0123456789ABCDEF'
    if nums < base:
        return digits[nums]
    else:
        return baseConversion2(nums // base, base) + digits[nums % base]

5.队列

  • 热土豆问题(约瑟夫问题)
def hotPotato(namelist, num):
    simqueue = Queue()
    # 全部加入队列
    for name in namelist:
        simqueue.enqueue(name)
    # 循环传递土豆,直到队列仅一个
    while simqueue.size() > 1:
        # 队首出,队尾进,循环num次
        for i in range(num):
            simqueue.enqueue(simqueue.dequeue())
        # 每隔num次,从队列出去一个
        simqueue.dequeue()
    # 返回最后一个人
    return simqueue.dequeue()
  • 回文序列
def palchecker(aString):
    stillEqual = True
    chardeque = Deque()

    # 把字符串一个个加入双端队列队末
    for ch in aString:
        chardeque.addRear(ch)

    # 双端队列大小>1且目前保持两端相等时
    while chardeque.size() > 1 and stillEqual:
        # 双端队列头弹出
        first = chardeque.removeFront()
        # 双端队列尾弹出
        last = chardeque.removeRear()
        # 判断是否头尾相等
        if first != last:
            stillEqual = False
    return stillEqual

6.递归

  • 数列求和
def sumArray(lis):
    """
    数组求和
    """
    if len(lis) == 1:
        return lis[0]
    else:
        return lis[0] + sumArray(lis[1:])
  • 汉诺塔
def hanoiTower(n):
    """
    开始柱->中间柱->目标柱
    """
    steps = []

    def move(n, A, B, C):
        """
        A:fromPlace(开始柱)
        B:withPlace(中间柱)
        C:toPlace(目标柱)
        """
        if n >= 1:
            # 开始柱移到中间柱
            move(n - 1, A, C, B)
            # 记录移动步骤
            steps.append(f'{A}->{C}')
            # 中间柱移到目标柱
            move(n - 1, B, A, C)

    move(n, '#1', '#2', '#3')
    return steps

7.优化/动态规划

  • 找零兑换
def dpMakeChange(coinValueList, change, minCoins, coinsUsed):
    # 从1开始到change逐个计算最少硬币数
    for cents in range(change + 1):
        # 初始最大值
        coinCount = cents
        # 初始化新加硬币
        newCoin = 1
        # 循环各个面值
        for j in [c for c in coinValueList if c <= cents]:
            # 判断这个面值是否优于之前的结果(更少硬币)
            if minCoins[cents - j] + 1 < coinCount:
                # 记录当前这种配置的硬币数
                coinCount = minCoins[cents - j] + 1
                # 当前配置的硬币面值
                newCoin = j
        # 记录得到当前最少硬币数
        minCoins[cents] = coinCount
        # 本步骤加的硬币面值
        coinsUsed[cents] = newCoin
    # 返回最后一个结果
    return minCoins[change]


def printCoins(coinsUsed, change):
    coin = change
    while coin > 0:
        thisCoin = coinsUsed[coin]
        print(thisCoin)
        coin = coin - thisCoin
  • 博物馆大盗
def museumRobber(treasure, maxbag):
    # 初始化各种商品重量组合的最大价值
    m = {(i, w): 0 for i in range(len(treasure)) for w in range(maxbag + 1)}

    for i in range(1, len(treasure)):
        for w in range(1, maxbag + 1):
            # 装不下第i个商品
            if treasure[i]['w'] > w:
                # 不装第i个
                m[(i, w)] = m[(i - 1, w)]
            # 装得下第i个
            else:
                # 判断不装第i和装第i个哪种价值更大
                m[(i, w)] = max(m[(i - 1, w)],m[(i - 1, w - treasure[i]['w'])] + treasure[i]['v'])
    return m


m = {}


def museumRobber2(tr, w):
    """
    迭代方法
    """
    if tr == set() or w == 0:
        m[(tuple(tr), w)] = 0
        return 0
    elif (tuple(tr), w) in m:
        return m[(tuple(tr), w)]
    else:
        vmax = 0
        for t in tr:
            if t[0] <= w:
                # 逐个从集合中去掉某个商品,递归调用选出所有价值中最大值
                v = museumRobber2(tr - {t}, w - t[0]) + t[1]
                vmax = max(vmax, v)
        m[(tuple(tr), w)] = vmax
        return vmax

8.树

  • 表达式解析/求值/恢复原表达式
# 表达式树后序遍历
def postordereval(tree):
    opers = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.truediv}
    res1 = None
    res2 = None
    if tree:
        res1 = postordereval(tree.getLeftChild())
        res2 = postordereval(tree.getRightChild())
        if res1 and res2:
            return opers[tree.getRootVal()](res1, res2)
        else:
            return tree.getRootVal()

def buildParseTree(fpexp):
    fplist = fpexp.split()
    pStack = Stack()
    eTree = BinaryTree('')
    pStack.push(eTree)
    currentTree = eTree
    for i in fplist:
        # 如果是左括号,当前节点添加左子节点,新节点设为当前节点
        if i == '(':
            currentTree.insertLeft('')
            pStack.push(currentTree)
            currentTree = currentTree.getLeftChild()
        # 如果是数字,赋值给当前节点,其父节点设为当前节点
        elif i not in ['+', '-', '*', '/', ')']:
            currentTree.setRootVal(int(i))
            parent = pStack.pop()
            currentTree = parent
        # 如果是运算符,赋给当前节点,并给当前节点加右子节点,新节点设为当前节点
        elif i in ['+', '-', '*', '/']:
            currentTree.setRootVal(i)
            currentTree.insertRight('')
            pStack.push(currentTree)
            currentTree = currentTree.getRightChild()
        # 如果是右括号,父节点设为当前节点
        elif i == ')':
            currentTree = pStack.pop()
        else:
            raise ValueError
    return eTree

9.图

  • 词梯问题
def wordproc():
    f = open("rawwords.txt", "r")
    wl = []
    for aline in f:
        l = aline.split()
        wl.append(l[0])
    of = open("fourletterwords.txt", "w")
    for w in wl:
        of.write(w + '\n')


def buildGraph(wordFile):
    d = {}
    g = Graph()
    wfile = open(wordFile, 'r')
    # create buckets of words that differ by one letter
    # 如果是4字母单词,属于4个桶
    for line in wfile:
        word = line[:-1]
        for i in range(len(word)):
            bucket = word[:i] + '_' + word[i + 1:]
            if bucket in d:
                d[bucket].append(word)
            else:
                d[bucket] = [word]
    # 给同一个桶的单词增加边和顶点
    for bucket in d.keys():
        for word1 in d[bucket]:
            for word2 in d[bucket]:
                if word1 != word2:
                    g.addEdge(word1, word2)
    return g


# 广度优先遍历
def bfs(g, start):
    start.setDistance(0)
    start.setPred(None)
    vertQueue = Queue()
    vertQueue.enqueue(start)
    while vertQueue.size() > 0:
        # 队首作为当前顶点
        currentVert = vertQueue.dequeue()
        # 遍历邻接节点
        for nbr in currentVert.getConnections():
            if nbr.getColor() == 'white':
                nbr.setColor('gray')
                nbr.setDistance(currentVert.getDistance() + 1)
                nbr.setPred(currentVert)
                vertQueue.enqueue(nbr)
        currentVert.setColor('black')


# 回途追溯函数
def traverse(y):
    x = y
    while x.getPred():
        print(x.getId())
        x = x.getPred()
    print(x.getId())

if __name__ == '__main__':
    # 构建单词关系图
    wordgraph = buildGraph("fourletterwords.txt")
    # 广度优先搜索
    bfs(wordgraph, wordgraph.getVertex('FOOL'))
    # 遍历找词路径
    traverse(wordgraph.getVertex('SAGE'))
    # traverse(wordgraph.getVertex('COOL'))
  • 骑士周游/Warnsdorff改进
def genLegalMoves(x, y, bdSize):
    newMoves = []
    moveOffsets = [(-1, -2), (-1, 2), (-2, -1), (-2, 1),
                   (1, -2), (1, 2), (2, -1), (2, 1)]
    for i in moveOffsets:
        newX = x + i[0]
        newY = y + i[1]
        if legalCoord(newX, bdSize) and legalCoord(newY, bdSize):
            newMoves.append((newX, newY))
    return newMoves


def legalCoord(x, bdSize):
    if 0 <= x < bdSize:
        return True
    else:
        return False


def knightGraph(bdSize):
    ktGraph = Graph()
    for row in range(bdSize):
        for col in range(bdSize):
            nodeId = posToNodeId(row, col, bdSize)
            newPositions = genLegalMoves(row, col, bdSize)
            for e in newPositions:
                nid = posToNodeId(e[0], e[1], bdSize)
                ktGraph.addEdge(nodeId, nid)
    return ktGraph


def knightTour(n, path, u, limit):
    # n=层次,path=路径,u=当前节点,limit=搜索总深度
    u.setColor('gray')
    # 当前节点加入路径
    path.append(u)
    if n < limit:
        # 对所有合法移动逐一深入
        nbrList = list(u.getConnections())
        i = 0
        done = False
        while i < len(nbrList) and not done:
            # 深入未经过的顶点
            if nbrList[i].getColor() == 'white':
                # 层次加一,递归深入
                done = knightTour(n + 1, path, nbrList[i], limit)
            i = i + 1
        # 无法完成总深度,回溯,试本层下一个顶点
        if not done:  # prepare to backtrack
            path.pop()
            u.setColor('white')
    else:
        done = True
    return done


def posToNodeId(row, col, bdSize):
    return row * bdSize + col


# Warnsdorff改进
def orderByAvail(n):
    resList = []
    for v in n.getConnections():
        if v.getColor() == 'white':
            c = 0
            for w in v.getConnections():
                if w.getColor() == 'white':
                    c = c + 1
            resList.append((c, v))
    resList.sort(key=lambda x: x[0])
    return [y[1] for y in resList]


def knightTourBetter(n, path, u, limit):  # use order by available function
    u.setColor('gray')
    path.append(u)
    if n < limit:
        # 具有最少合法移动目标的格子优先搜索
        nbrList = orderByAvail(u)
        i = 0
        done = False
        while i < len(nbrList) and not done:
            if nbrList[i].getColor() == 'white':
                done = knightTour(n + 1, path, nbrList[i], limit)
            i = i + 1
        if not done:  # prepare to backtrack
            path.pop()
            u.setColor('white')
    else:
        done = True
    return done


if __name__ == '__main__':
    kg = knightGraph(5)  # five by five solution
    thepath = []
    start = kg.getVertex(4)
    knightTourBetter(0, thepath, start, 24)
    for v in thepath:
        print(v.getId())
  • 最短路径
def dijkstra(aGraph, start):
    # 对所有顶点建堆,形成优先队列
    pq = PriorityQueue()
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in aGraph])
    while not pq.isEmpty():
        # 优先队列出队
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newDist = currentVert.getDistance() + currentVert.getWeight(nextVert)
            # 修改出队顶点所邻接顶点的dist,并逐个重排队列
            if newDist < nextVert.getDistance():
                nextVert.setDistance(newDist)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert, newDist)
  • 最小生成树
def prim(G,start):
    pq = PriorityQueue()
    for v in G:
        v.setDistance(sys.maxsize)
        v.setPred(None)
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in G])
    while not pq.isEmpty():
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newCost = currentVert.getWeight(nextVert)
            if nextVert in pq and newCost< nextVert.getDistance():
                nextVert.setDistance(newCost)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert, newCost)
  • 图深度遍历
class dfsgraph(Graph):
    def __init__(self):
        super().__init__()
        self.time = 0

    def dfs(self):
        # 颜色初始化
        for aVertex in self:
            aVertex.setColor('white')
            aVertex.setPred(-1)
        # 如果还有未包括的顶点则建森林
        for aVertex in self:
            if aVertex.getColor() == 'white':
                self.dfsvisit(aVertex)

    def dfsvisit(self, startVertex):
        startVertex.setColor('gray')
        # 算法的步数
        self.time += 1
        startVertex.setDiscovery(self.time)
        # 深度优先递归访问
        for nextVertex in startVertex.getConnections():
            if nextVertex.getColor() == 'white':
                nextVertex.setPred(startVertex)
                self.dfsvisit(nextVertex)
        startVertex.setColor('black')
        self.time += 1
        startVertex.setFinish(self.time)

10.其他

  • 旅行商问题
解决方法:近似(KNN) / 二叉树
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值