遍歷二叉樹的神級方法
分別按照二叉樹先序,中序和後序列印所有的節點。
輸入描述:
第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。
以下 n 行每行三個整數 fa,lch,rch,表示 fa 的左兒子為 lch,右兒子為 rch。(如果 lch 為 0 則表示 fa 沒有左兒子,rch同理)
輸出描述:
輸出三行分別表示二叉樹的前序,中序和後序遍歷。
要求:時間複雜度為o(n
)o(n)
o(n)
,額外的空間複雜度為o(1
)o(1)
o(1)
示例1輸入
3 1
1 2 3
2 0 0
3 0 0
輸出1 2 3
2 1 3
2 3 1
備註:
1 ≤n
≤106
1 \leq n \leq 10^6
1≤n≤1061≤
fa,l
ch,r
ch,r
oot≤
n1 \leq fa,lch,rch,root \leq n
1≤fa,l
ch,r
ch,r
oot≤
n 題解:先序遍歷、中序遍歷和後續遍歷沒什麼好說的,但是這題要求額外的空間的複雜度為o(1
)o(1)
o(1)
,無論是遞迴還是非遞迴,我們需要的額外空間複雜度為o(h
)o(h)
o(h)
,h 為樹的高度。究其原因:因為每個節點都有指向孩子節點的指標,所以從上層到下層容易,但是沒有指向父節點的指標,所以從下層到上層需要用棧結構輔助完成。
moris遍歷的實質是就是避免使用棧結構,而是讓下層到上層有指標,具體就是讓底層節點指向 null 的空閒指標指向上層的某個節點,從而完成下層到上層的移動。
具體參考:moris遍歷
**:
#include
#include
using
namespace std;
struct bst };
bst *
createtree()
if(lch &&
!hash.
count
(lch))if
(rch &&
!hash.
count
(rch))if
(lch) hash[fa]
->lch = hash[lch];if
(rch) hash[fa]
->rch = hash[rch];}
return hash[rt];}
void
morispreorder
(bst *root)
else
}else
cur1 = cur1-
>rch;
}puts(""
);}void
morisinorder
(bst *root)
else
}printf
("%d "
, cur1-
>val)
; cur1 = cur1-
>rch;
}puts(""
);}bst *
reverseedge
(bst *root)
return pre;
}void
printedge
(bst *root)
reverseedge
(tail);}
void
morispost
(bst *root)
else
} cur1 = cur1-
>rch;
}printedge
(root)
;puts(""
);}int
main
(void
)
Morris神級遍歷二叉樹
morris遍歷是二叉樹遍歷演算法的超強高階演算法,跟遞迴 非遞迴 棧實現 的空間複雜度,morris遍歷可以將非遞迴遍歷中的空間複雜度降為o 1 從而實現時間複雜度為o n 而空間複雜度為o 1 的精妙演算法。morris遍歷利用的是樹的葉節點左右孩子為空 樹的大量空閒指標 實現空間開銷的極限縮減...
二叉樹遍歷方法
二叉樹簡介 二叉樹是每個節點最多有兩個子樹的樹結構。通常被稱作左子樹 left subtree 和右子樹 right subtree 二叉樹常被用於實現二叉查詢樹二叉堆。二叉樹 深度為k 並且有2 k 1個節點的二叉樹稱為滿二叉樹。這種樹的特點是每一層的節點數都是最大節點數。而且在一棵二叉樹中,除最...
二叉樹的遍歷方法
二叉樹的遍歷有三種方式,如下 1 前序遍歷 dlr 首先訪問根結點,然後遍歷左子樹,最後遍歷右子樹。簡記根 左 右。2 中序遍歷 ldr 首先遍歷左子樹,然後訪問根結點,最後遍歷右子樹。簡記左 根 右。3 後序遍歷 lrd 首先遍歷左子樹,然後遍歷右子樹,最後訪問根結點。簡記左 右 根。例1 如上圖...