小魚要學數據結構與算法(基於python)—Day19樹的遍歷、優先隊列和二叉堆

樹的遍歷、優先隊列和二叉堆

在這裏插入圖片描述

一、知識概覽

本章主要講樹的遍歷、優先隊列和二叉堆及實現。

1.1 樹的遍歷

主要有前序遍歷,後序遍歷,中序遍歷三種方法
樹的遍歷

1.2 優先隊列和二叉堆

由優先隊列引出二叉堆,最小堆,最大堆的概念。介紹二叉堆數據結構常用操作。
在這裏插入圖片描述

1.3二叉堆的實現

用非嵌套列表來實現二叉堆。另外,可以用二叉堆進行排序,給排序提供新思路。
二叉堆實現

二、代碼實現

2.1 樹的遍歷

三種遍歷方法:

# 樹的遍歷:遞歸算法
# 前序遍歷
def preorder(tree):
    if tree:
        print(tree.getRootVal())
        preorder(tree.getLeftChild())
        preorder(tree.getRightChild())
# 後序遍歷
def postorder(tree):
    if tree != None:
        postorder(tree.getLeftChild())
        postorder(tree.getRightChild())
        print(tree.getRootVal())

# 中序遍歷
def inorder(tree):
    if tree != None:
        inorder(tree.getLeftChild())
        print(tree.getRootVal())
        inorder(tree.getRightChild())

將後序遍歷用於表達式求值問題。

# 後序遍歷:表達式求值
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 printexp(tree):
    sVal = ''
    if tree:
        sVal = '(' + printexp(tree.getLeftChild())
        sVal = sVal + str(tree.getRootVal())
        sVal = sVal + printexp(tree.getRightChild()) + ')'
    return sVal

2.2 二叉堆操作實現

#二叉堆操作實現
class BinHeap:
    def __init__(self):
        self.heapList=[0]
        self.curentSize=0
#insert代碼
    def percUp(self,i):
        while i//2>0:#沿路徑向上
            if self.heapList[i]<self.heapList[i//2]:
                tmp=self.heapList[i//2]
                self.heapList[i//2]=self.heapList[i]
                self.heapList[i]=tmp
            i=i//2#沿路徑向上
    def insert(self,k):
        self.heapList.append(k)
        self.curentSize=self.curentSize+1
        self.percUp(self.curentSize)#新key上浮
    def delMin(self):
        retval=self.heapList[1]
        self.heapList[1]=self.heapList[self.curentSize]
        self.curentSize=self.curentSize-1
        self.heapList.pop()#移除最後一個
        self.perDown(1)#新頂下沉
        return retval
    def perDown(self,i):
        while (i*2)<=self.curentSize:
            mc=self.minChild(i)#子節點中最小的那個key
            if self.heapList[i]>self.heapList[mc]:
                tmp=self.heapList[i]
                self.heapList[i]=self.heapList[mc]
                self.heapList[mc]=tmp#比最小子節點大則交換下沉
            i=mc#沿路徑下降
    def minChild(self,i):
        if i*2+1>self.curentSize:#唯一子節點
            return i*2
        else:
            if self.heapList[i*2]<self.heapList[i*2+1]:#如有兩個子節點選較小
                return i*2
            else:
                return i*2+1
    def buildHeap(self,alist):
        i=len(alist)//2
        self.curentSize=len(alist)
        self.heapList=[0]+alist[:]
        print(len(self.heapList),i)
        while (i>0):
            print(self.heapList,i)
            self.perDown(i)
            i=i-1#
        print(self.heapList,i)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章