python實戰--數據結構二叉樹


此文將講述如何用python實戰解決二叉樹實驗
數據結構

前面已經講述了python語言的基本用法,現在讓我們實戰一下具體明確python的用法
點擊我進入python速成筆記

先看一下最終效果圖:

首先我們要定義二叉樹結點的一個類,在python中定義二叉樹結點代碼如下:

#二叉鏈表
class BiTree:
    def __init__(self, elementType=None, lchild=None, rchild=None):
        self.elementType = elementType
        self.lchild = lchild
        self.rchild = rchild

其次初始化二叉樹頭結點的代碼如下:

#初始化二叉樹新建頭結點
def initTree(s):
    temp=BiTree()
    ptree=BiTree("A",temp,temp)
    if s[2]==0:
        ptree.lchild=None
    if s[4]==0:
        ptree.rchild=None
    return ptree,temp

二叉樹中經常需要訪問子節點,那么子節點的代碼:

#尋找下一個結點
def getNext(tree,temp):
    if(tree.lchild ==temp ):
        return tree
    if (tree.lchild!=None):
        if(getNext(tree.lchild,temp)!=None):
            return getNext(tree.lchild,temp)
    if (tree.rchild==temp):
        return tree
    if(tree.rchild !=None):
        if (getNext(tree.rchild,temp) != None):
            return getNext(tree.rchild,temp)
    return None

有了頭結點也能找到子節點,那么繪圖二叉樹的代碼如下:
繪圖需要傳入圖形窗口對象,根節點,初始根節點x,y坐標以及深度1

#畫出二叉樹圖
def drawroot(graph,root,x,y,deep):
    # 畫橢圓
    oval = Oval(Point(x-20, y-20), Point(x+20, y+20))
    oval.setFill('blue')  # 填充顏色
    oval.draw(graph)
    # 顯示文字
    message = Text(Point(x, y), root.elementType)
    message.draw(graph)
    if(root.lchild!=None):
        # 畫線
        line = Line(Point(x - 10, y + 10), Point(x - 30*deep, y + 60))
        line.draw(graph)
        drawroot(graph,root.lchild,x-30*deep,y+60,deep-1)
    if(root.rchild!=None):
        # 畫線
        line = Line(Point(x+10, y + 10), Point(x + 30*deep, y + 60))
        line.draw(graph)
        drawroot(graph, root.rchild, x + 30*deep, y + 60,deep-1)

如何快速生成二叉樹需要動用文件,根據文件鏈接子樹代碼:
讀入根節點和一個臨時結點,根節點名字和是否有左右子樹開始鏈接

#根據文件建立二叉鏈表
def getTree(tree,temp,name,left,right):
    child=BiTree(name,temp,temp)
    if(not left):
        child.lchild=None
    if(not right):
        child.rchild=None
    if(tree.lchild==temp):
        tree.lchild=child
    elif(tree.rchild==temp):
        tree.rchild=child

具體完整讀取代碼完全鏈接子樹代碼如下:

input = open('bt31.txt', 'r')
s = []
try:
    for line in input:
        s.append(line)
finally:
    input.close()
ptree, temp = initTree(s[0])
for i in range(len(s)):
    if i != 0:
        getTree(getNext(ptree, temp), temp, s[i][0], eval(s[i][2]), eval(s[i][4]))

然后生成圖形窗口繪制上面二叉樹代碼為:

gragh = GraphWin('CSSA', 1200, 700)
    drawroot(gragh, ptree, 500, 20, 4)

效果如下:

以上便是二叉樹生成的前提操作,后面代碼即為數據結構實驗五二叉樹1-10題必做題源代碼以及12,13,15選做題源碼:



#三種二叉遍歷

def DLR(tree):
    order=[]
    if(tree!=None):
        order.append(tree.elementType)
        if(tree.lchild!=None):
            order=order+DLR(tree.lchild)
        if(tree.rchild!=None):
            order=order+DLR(tree.rchild)
    return order
def LDR(tree):
    order=[]
    if (tree != None):
        if (tree.lchild != None):
            order = order + LDR(tree.lchild)
        order.append(tree.elementType)
        if (tree.rchild != None):
            order = order + LDR(tree.rchild)
    return order
def LRD(tree):
    order=[]
    if (tree != None):
        if (tree.lchild != None):
            order = order + LRD(tree.lchild)
        if (tree.rchild != None):
            order = order + LRD(tree.rchild)
        order.append(tree.elementType)
    return order


#打印題目一信息
def exp1(gragh,ptree):
    str=""
    str += "先序遍歷:"
    for i in range(len(DLR(ptree))):
        str+=DLR(ptree)[i]
    str +="\n"
    str += "中序遍歷:"
    for i in range(len(LDR(ptree))):
        str +=LDR(ptree)[i]
    str +="\n"
    str += "后序遍歷:"
    for i in range(len(LRD(ptree))):
        str +=LRD(ptree)[i]
    str +="\n"
    message = Text(Point(200, 400), "1.打印出二叉樹的三種遍歷序\n"+str)
    message.draw(gragh)

#遍歷結點層次
def DLRDeep(tree,deep):
    order=""
    if(tree!=None):
        order=order+tree.elementType+"        "+repr(deep)+"\n"
        if(tree.lchild!=None):
            order=order+DLRDeep(tree.lchild,deep+1)
        if(tree.rchild!=None):
            order=order+DLRDeep(tree.rchild,deep+1)
    return order
def exp2(gragh,ptree):
    str=DLRDeep(ptree,1)
    message = Text(Point(1000, 300), "2.輸出各結點的層次\n"+str)
    message.draw(gragh)


#查找樹的高度

def height(tree):
    h=0
    if(tree!=None):
        left=height(tree.lchild)
        right=height(tree.rchild)
        if(left>right):
            h=left+1
        else :
            h=right+1
    return h
def exp3(gragh,ptree):
    str="3.該二叉樹高度為"+repr(height(ptree))
    message = Text(Point(500, 350), str)
    message.draw(gragh)


#查詢結點數量

def getnum(tree):
    num=0
    if(tree!=None):
        num=num+1
        num+=getnum(tree.lchild)
        num+=getnum(tree.rchild)
    return num
def exp4(gragh,ptree):
    str="4.該二叉樹結點數為"+repr(getnum(ptree))
    message = Text(Point(500, 400), str)
    message.draw(gragh)


#查詢葉子結點數量

def getleaf(tree):
    num=0
    if(tree!=None):
        num+=getleaf(tree.lchild)
        num+=getleaf(tree.rchild)
        if(tree.lchild==None and tree.rchild==None):
            return 1
    return num
def exp5(gragh,ptree):
    str="5.該二叉樹葉子結點數為"+repr(getleaf(ptree))
    message = Text(Point(500, 450), str)
    message.draw(gragh)


#查詢兩個度的結點數量

def getTwo(tree):
    num=0
    if(tree!=None):
        num+=getTwo(tree.lchild)
        num+=getTwo(tree.rchild)
        if(tree.lchild!=None and tree.rchild!=None):
            num+=1
    return num
def exp6(gragh,ptree):
    str="6.該二叉樹有兩個度的結點有:"+repr(getTwo(ptree))
    message = Text(Point(500, 500), str)
    message.draw(gragh)


#查詢父親結點,兄弟結點,子節點
def findFather(tree,name):
    if(tree!=None):
        if(tree.lchild!=None and tree.lchild.elementType==name):
            return tree
        if(tree.rchild!=None and tree.rchild.elementType==name):
            return tree
        if findFather(tree.rchild,name)!=None:
            return  findFather(tree.rchild,name)
        if findFather(tree.lchild,name)!=None:
            return  findFather(tree.lchild,name)
    return None
def info(tree,name):
    father=findFather(tree,name)
    if(father.lchild!=None and father.lchild.elementType==name):
        brother=father.rchild
        son1=father.lchild.lchild
        son2=father.lchild.rchild
    else :
        brother=father.lchild
        son1=father.rchild.lchild
        son2=father.rchild.rchild
    return father,brother,son1,son2
def exp7(gragh ,tree,name):
    str=""
    father,brother,son1,son2=info(tree,name)
    if(father==None):
        str+="8.父節點不存在"+"\n"
    else:
        str+="8.父節點為:"+repr(father.elementType)+"\n"
    if(brother==None):
        str+="兄弟結點不存在"+"\n"
    else:
        str+="兄弟結點為:"+repr(brother.elementType)+"\n"
    if(son1==None):
        str+="左子結點不存在"+"\n"
    else:
        str+="左子結點為:"+repr(son1.elementType)+"\n"
    if (son1 == None):
        str += "右子結點不存在"+"\n"
    else:
        str+="右子結點為:"+repr(son2.elementType)+"\n"
    message = Text(Point(400, 550), str)
    message.draw(gragh)

#查詢指定結點深度
def getdeep(tree,name,deep):   #EXP8
    if (tree != None):
        if (tree.elementType==name):
            return  deep
        deepleft=getdeep(tree.lchild,name,deep+1)
        deepright=getdeep(tree.rchild,name,deep+1)
        if(deepleft!=0):
            return  deepleft
        if(deepright!=0):
            return  deepright
    return 0
def exp8(gragh,tree,name):
    deep=getdeep(tree,name,1)
    if(deep==0):
        message = Text(Point(400, 500), "7.本結點不存在")
        message.draw(gragh)
        return 0
    else:
        message = Text(Point(400, 500), "7.本結點:"+repr(name)+"深度為"+repr(deep))
        message.draw(gragh)
        return 1
#順序存儲變為二叉鏈表存儲
def seqToNode(s,tree,i):

    if(tree!=None):
        if(i*2>len(s)):
            tree.lchild=None
        elif (s[i*2]==None) :
            tree.lchild=None
        else:
            temp = BiTree(s[i*2])
            tree.lchild=temp
        if(i*2+1>len(s)):
            tree.rchild=None
        elif (s[i*2+1]==None):
            tree.rchild=None
        else:
            temp = BiTree(s[i*2 + 1])
            tree.rchild=temp
        seqToNode(s,tree.lchild,i*2)
        seqToNode(s,tree.rchild,i*2+1)

#交換左右二叉樹

def change(tree):#     EXP10
    if(tree!=None):
        temp=tree.lchild
        tree.lchild=tree.rchild
        tree.rchild=temp
    if(tree.lchild!=None):
        change(tree.lchild)
    if(tree.rchild!=None):
        change(tree.rchild)

#找所有結點的路徑
def road(s,tree,all):
    if(tree.rchild==None and tree.lchild==None):
        all.append(repr(tree.elementType))
        all.append("到根節點的路徑為"+reverse1(s)+"A"+"\n")
    if(tree.lchild!=None):
        road(s+tree.lchild.elementType,tree.lchild,all)
    if(tree.rchild!=None):
        road(s+(tree.rchild.elementType),tree.rchild,all)
def exp12(all,gragh,ptree):
    str=""
    road(str, ptree, all)
    for i in range (len(all)):
        str+=all[i]

    message = Text(Point(150, 450), "12.從每個葉子結點到根結點的路徑:\n"+str)
    message.draw(gragh)

#按層次打印結點
def exp13(gragh,tree):
    que=Queue()
    que.enqueue(tree)
    str="13.結點按層次打印結果為\n"
    while(not que.isEmpty()):
        if(que.getTop().lchild!=None):
            que.enqueue(que.getTop().lchild)
        if(que.getTop().rchild!=None):
            que.enqueue(que.getTop().rchild)
        str+=repr(que.getTop().elementType)
        que.outqueue()
    message = Text(Point(600, 400), str)
    message.draw(gragh)


#查找最長路徑
def maxpath(temp,tree,path,deep):
    if (tree.rchild == None and tree.lchild == None):
        return temp,deep
    deep1,deep2=0,0
    if (tree.lchild != None):
        path1,deep1=maxpath(temp + tree.lchild.elementType, tree.lchild, path,deep+1)
    if (tree.rchild != None):
        path2,deep2=maxpath(temp + (tree.rchild.elementType), tree.rchild, path,deep+1)
    if(deep1>deep2):
        return  path1,deep1
    else :
        return  path2,deep2
def exp15(gragh,tree):
    temp=""
    path=""
    path,deep=maxpath(temp,tree,path,1)
    message = Text(Point(600, 500), "15.該二叉樹最長路徑為:\nA"+path+"\n長度為"+repr(deep))
    message.draw(gragh)

值得注意的是13題需要用到隊列,需要提前寫好隊列的代碼如下:

class Queue:
    """模擬隊列"""

    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0, item)

    def outqueue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)
    def getTop(self):
        return self.items[self.size()-1]

上述便是代碼的全部代碼,效果如下


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM