二叉樹先序、中序、后序、層次遍歷的非遞歸實現(python)


class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None

'''先序遍歷'''
#先序遍歷(非遞歸法1)
def preOrder(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
'''
思路分析:
preOrder每次都將遇到的節點壓入棧,當左子樹遍歷完畢后才從棧中彈出最后一個訪問的節點,訪問其右子樹。
在同一層中,不可能同時有兩個節點壓入棧,因此棧的大小空間為O(h),h為二叉樹高度。
時間方面,每個節點都被壓入棧一次,彈出棧一次,訪問一次,復雜度為O(n)。
'''
if root == None:
return []
stack = []
result = []
while root or stack:
while root: # 從根節點開始,一直找它的左子樹
result.append(root.val)
stack.append(root)
root = root.left # while結束表示當前節點為空,即前一個節點沒有左子樹了
root = stack.pop()
root = root.right # 開始查看它的右子樹
return result

# 先序遍歷(非遞歸法2)
def preOrder2(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if root == None:
return []
stack = [root]
result = []
while stack:
result.append(root.val)
if root.right:
stack.append(root.right)
if root.left:
stack.append(root.left)
root = stack.pop()
return result


'''中序遍歷'''
def inorder(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
'''
思路分析(利用棧實現):
1. 使用一個棧保存結點(列表實現);
2. 如果結點存在,入棧,然后將當前指針指向左子樹,直到為空;
3. 當前結點不存在,則出棧棧頂元素,並把當前指針指向棧頂元素的右子樹;
4. 棧不為空,則循環步驟2、3。
'''
if root == None:
return []
stack = []
result = []
while root or stack:
if root:
stack.append(root)
root = root.left
else:
root = stack.pop()
result.append(root.val)
root = root.right
return result


'''后序遍歷'''
def postOrder(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
'''
思路分析:
后序遍歷對比中序遍歷難度要大一些。因為中序遍歷節點序列有一點的連續性,
而后續遍歷則感覺有一定的跳躍性。先左,再右,最后才中間節點;
訪問左子樹后,需要跳轉到右子樹,右子樹訪問完畢了再回溯至根節點並訪問之。
'''
stack = [root]
stack2 = []
result = []
while len(stack) > 0:
root = stack.pop()
stack2.append(root)
if root.left:
stack.append(root.left)
if root.right:
stack.append(root.right)
while len(stack2) > 0:
node = stack2.pop()
result.append(node.val)
return result


'''層次遍歷'''
# 層次遍歷法1:先進后出選用棧結構
def levelOrder(root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if root == None:
return []
result = []
level = []
now_list = [root]
next_list = []
while len(now_list) != 0:
while len(now_list) != 0:
temp = now_list.pop(0)
level.append(temp.val)
if temp.left:
next_list.append(temp.left)
if temp.right:
next_list.append(temp.right)
result.append(level)
now_list, next_list = next_list, []
level = []
return result
# 層次遍歷法2:先進先出選用隊列結構
import queue
def levelOrder2(root):
if root == None:
return []
level = []
result = []
now_que = queue.Queue() # 創建先進先出隊列
next_que = queue.Queue()
now_que.put(root)
while not now_que.empty():
while not now_que.empty():
root = now_que.get()
level.append(root.val)
if root.left: # 若該節點存在左子節點,則加入隊列(先push左節點)
next_que.put(root.left)
if root.right: # 若該節點存在右子節點,則加入隊列(再push右節點)
next_que.put(root.right)
result.append(level)
now_que = next_que
next_que = queue.Queue()
level = []
return result

'''Test---[1,6,2,3]'''
testTree = TreeNode(1)
root = testTree
root.left = TreeNode(6)
root.right = TreeNode(2)
root = root.right
root.left = TreeNode(3)
root = testTree # 返回到根節點

print('先序遍歷法1:',preOrder(root))
print('先序遍歷法2:',preOrder2(root))
print('中序遍歷:',inorder(root))
print('后序遍歷:',postOrder(root))
print('層次遍歷法1:',levelOrder(root))
print('層次遍歷法2:',levelOrder2(root))


免責聲明!

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



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