二叉樹展開為連結串列
阿新 • • 發佈:2020-08-07
題目描述:
給定一個二叉樹,原地將它展開為一個單鏈表。
例如,給定二叉樹
1
/ \
2 5
/ \ \
3 4 6
將其展開為:
1 \ 2 \ 3 \ 4 \ 5 \ 6
解法一
我們需要兩步完成這道題。
- 將左子樹插入到右子樹的地方
- 將原來的右子樹接到左子樹的最右邊節點
考慮新的右子樹的根節點,一直重複上邊的過程,直到新的右子樹為 null
過程如下展示
1 / \ 2 5 / \ \ 3 4 6 //將 1 的左子樹插入到右子樹的地方 1 \ 2 5 / \ \ 3 4 6 //將原來的右子樹接到左子樹的最右邊節點 1 \ 2 / \ 3 4 \ 5 \ 6 //將 2 的左子樹插入到右子樹的地方 1 \ 2 \ 3 4 \ 5 \ 6 //將原來的右子樹接到左子樹的最右邊節點 1 \ 2 \ 3 \ 4 \ 5 \ 6
//go func flatten(root *TreeNode) { for root != nil { if root.Left == nil { root = root.Right }else { pre := root.Left for pre.Right != nil { pre = pre.Right } pre.Right = root.Right root.Right = root.Left root.Left = nil root = root.Right } } }
方法二
先序遍歷為1-2-3-4-5-6,如果按照先序遍歷執行,1的左孩子為nil,右孩子為2,但是5就沒了。所以不能直接使用先序遍歷。
但是我們可以逆先序遍歷:6-5-4-3-2-1
然後每遍歷一個節點就將當前節點的右指標更新為上一個節點。
遍歷到 5,把 5 的右指標指向 6。6 <- 5 4 3 2 1。
遍歷到 4,把 4 的右指標指向 5。6 <- 5 <- 4 3 2 1。
……
(這個思想打個比方就像接鏈條,我們先把尾部的接好,在往頭部拼接,整體就串起來了)
//go func flatten(root *TreeNode) { if root==nil{ return } var pre *TreeNode //使用2重指標 dfs(root,pre) } func dfs(root *TreeNode,pre *TreeNode){ if root==nil{ return } dfs(root.Right,pre) dfs(root.Left,pre) root.Right= pre root.Left=nil pre =root }