寫在開頭的話:
當想寫這個的時候,發現已經有人做了這個工作了,詳情請見Python基礎算法/劍指offer,然而依然決定自己寫下這個系列,作爲算法部分的鞏固和提高。在自己寫完後會借鑑Python基礎算法/劍指offer的代碼,如有部分重複,還請見諒。
書上的方法是用兩個棧來完成,看到有面試題讓用一個隊列來完成,這裏用一個list來完成吧,代碼如下:
# -*- coding: UTF-8 -*-.
class Node(object):
"""節點類"""
def __init__(self, data = -1, lchild = None, rchild = None, isEmpty = 0):
self.data = data
self.lchild = lchild
self.rchild = rchild
self.isEmpty = isEmpty
class BinaryTree(object):
"""樹類"""
def __init__(self):
self.root = Node(isEmpty = 1)
def add(self, data):
"""爲樹增加節點,建立二叉查找樹"""
node = Node(data)
if self.root.isEmpty == 1:
self.root = node
else:
treeNode = self.root
while(1):
if node.data <= treeNode.data:
if treeNode.lchild == None:
treeNode.lchild = node
break
else:
treeNode = treeNode.lchild
else:
if treeNode.rchild == None:
treeNode.rchild = node
break
else:
treeNode = treeNode.rchild
def printTree(self):
"""按之字形順序打印二叉樹"""
if self.root == None:
return
myList = [self.root]
flagForward = 0# 爲0表示下一行逆序打印,爲1表示下一行正序打印
# 記錄該行的節點數目和下一行的節點數目
numberNow, numberNext = 1, 0
while(numberNow or numberNext):
# 表示在該行查找
if numberNow:
# 總是將先放入的先打印出來
node = myList.pop(0)
numberNow -= 1
print node.data,
# 根據flagForward的值改變左右子樹的打印數學
if flagForward:
if node.rchild:
myList.insert(numberNow, node.rchild)
numberNext += 1
if node.lchild:
myList.insert(numberNow, node.lchild)
numberNext += 1
else:
if node.lchild:
myList.insert(numberNow, node.lchild)
numberNext += 1
if node.rchild:
myList.insert(numberNow, node.rchild)
numberNext += 1
# 表示該行結束了
else:
# 下一行變成該行
if numberNext:
numberNow, numberNext = numberNext, 0
# 正方向逆序
flagForward = ~flagForward
def test():
'Test the program.'
arr = [5, 6, 1, 4, 2, 69, -1, 24]
tree = BinaryTree()
for item in arr:
tree.add(item)
# 5
# / \
# 1 6
# / \ \
# -1 4 69
# / /
# 2 24
print '按之字形順序打印二叉樹:'
tree.printTree()
if __name__ == "__main__":
test()# 5 6 1 -1 4 69 24 2
由於list的pop(0)和insert()都不是O(1)的操作,因此時間複雜度較高,感覺是一個明顯的缺點。。。