Python二叉樹的構建 解析與遍歷

2021-10-07 16:19:52 字數 5002 閱讀 4715

一、二叉樹的構建有兩種方法:

1.列表之列表 2.節點與引用(使用遞迴)

①列表之列表:使用python特有的列表結構,用巢狀的形式進而實現,每個父節點預設有兩個子節點,可以為空

def binarytree(r):

return [r,,]

def insertleft(root,newbranch):

t=root.pop(1)

if len(t)>1:

root.insert(1,[newbranch,t,])

else:

root.insert(1,[newbranch,,])

def insertright(root,newbranch):

t=root.pop(2)

if len(t)>1:

root.insert(2,[newbranch,t,])

else:

root.insert(2,[newbranch,,])

def getrootval(root):

return root[0]

def getrootval(root):

return root[0]

def setrootval(root,newval):

root[0]=newval

def getleftchild(root):

return root[1]

def getrightchild(root):

return root[2]

a=binarytree(3)

insertleft(a,5)

insertleft(a,4)

insertright(a,9)

l=getleftchild(a)

setrootval(l,'a')

print(a)

②節點與引用:運用遞迴的思想,所有二叉樹的子樹也是二叉樹

class binarytree():

def __init__(self,rootobj):

self.key=rootobj

self.leftchild=none

self.rightchild=none

def insertleft(self,newobj):

if self.leftchild:

t=binarytree(newobj)

t.leftchild=self.leftchild #注意和後面一行的順序

self.leftchild=t

else:

self.leftchild=binarytree(newobj)

def insertright(self,newobj):

if self.rightchild:

t=binarytree(newobj)

t.rightchild=self.rightchild #注意和後面一行的順序

self.rightchild=t

else:

self.rightchild=binarytree(newobj)

def getleftchild(self):

return self.leftchild

def getrightchild(self):

return self.rightchild

def setrootval(self,obj):

self.key=obj

def getrootval(self):

return self.key

r=binarytree('a')

print(r.getrootval())

r.insertleft('a')

print(r.getleftchild())

print(r.getleftchild().getrootval())

r.getleftchild().setrootval('b')

print(r.getleftchild().getrootval())

二、二叉樹的解析和計算

①解析原理:使用完全括號法構建二叉樹

1.遇到(,就為當前節點新增乙個左節點,並下沉到該子節點;

2.遇到符號,就將當前節點的值設為當前標記的運算子,並新增乙個右節點,並下沉;

3.遇到數字,就將當前節點的值設為這個數,然後返回至父節點;

4.遇到),就返回父節點

from pythonds.trees import binarytree

from pythonds.basic import stack

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 in ['+','-','*','/']:

currenttree.setrootval(i)

currenttree.insertright('')

pstack.push(currenttree)

currenttree=currenttree.getrightchild()

elif i not in ['+','-','*','/',')']:

currenttree.setrootval(int(i))

parent=pstack.pop()

currenttree=parent

else:

currenttree=pstack.pop()

return etree

pt = buildparsetree("( ( 10 + 5 ) * 3 )")

print(pt.getleftchild().getrootval())

②計算(一般單獨作為外部函式,也可以放到類裡面)

import operator

def evaluate(parsetree):

opers=

leftc=parsetree.getleftchild()

rightc=parsetree.getrightchild()

if leftc and rightc: #帶節點的子樹

fn=opers[parsetree.getrootval()]

return fn(evaluate(leftc),evaluate(rightc)) #遞迴呼叫

else: #沒有子節點的節點

return parsetree.getrootval()

pt = buildparsetree("( ( 10 + 5 ) * 3 )")

print(evaluate(pt))

三、二叉樹的遍歷

①前序遍歷:

def preorder(tree):

if tree:

print(tree.getrootval())

preorder(tree.getleftchild())

preorder(tree.getrightchild())

pt = buildparsetree("( ( 10 + 5 ) * 3 )")

preorder(pt)

②後序遍歷:(不知道書中為什麼給的是左-右-根)

def postorder(tree):

if tree:

postorder(tree.getleftchild())

postorder(tree.getrightchild())

print(tree.getrootval())

pt = buildparsetree("( ( 10 + 5 ) * 3 )")

postorder(pt)

③中序遍歷

def inorder(tree):

if tree:

inorder(tree.getleftchild())

print(tree.getrootval())

inorder(tree.getrightchild())

pt = buildparsetree("( ( 10 + 5 ) * 3 )")

print(inorder(pt))

④用括號展示二叉樹

中序

後序(但書中的彷彿是左-右-根)

構建二叉樹 遍歷二叉樹

陣列法構建二叉樹 public class main public static void main string args 用陣列的方式構建二叉樹 public static void createbintree 把linkedlist集合轉成二叉樹的形式 for int j 0 j 最後乙個父節...

構建二叉樹

前序遍歷構建二叉樹是根據根節點 左節點 右節點的方式輸入資料,針對乙個節點來說,首先輸入的是根節點,根節點之後的數值應該是其左子節點,之後是右節點,如果是遞迴,則首先是一直設定左節點,之後再依次設定右節點。之前在看二叉樹過程中,見過最多的是輸入個位數字構建二叉樹,今天看到乙個可以輸入多個數字的輸入方...

二叉樹的構建

二叉樹包括順序儲存和鏈式儲存,這裡只說鏈式儲存,二叉樹的每個結點和雙鏈表有些類似,但是數的結構要比雙鏈表複雜,在構造樹的過程中涉及到遞迴呼叫的問題,遞迴的問題往往是很複雜的問題,因此,這裡單獨說二叉樹的構建。include include include 定義二叉樹 typedef struct n...