面試題23:二叉樹的遍歷演算法
阿新 • • 發佈:2018-12-25
一. 構造二叉樹
構造二叉樹,先得要構建一個樹的節點,定義一個TreeNode:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
插入節點,建立新樹:
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
二. 二叉樹的遞迴遍歷演算法
三種遍歷方法,先序,中序,後序,都是用遞迴方法:
1. 先序遍歷
public void preorderTraversal(TreeNode root,ArrayList<Integer> ret){
int rootvalue = root.val;
ret.add(rootvalue);
if(root.left != null){
inorderTraversal(root.left,ret);
}
if(root.right != null){
inorderTraversal(root.right ,ret);
}
}
2. 中序遍歷
public void inorderTraversal(TreeNode root,ArrayList<Integer> ret){
if(root.left != null){
inorderTraversal(root.left,ret);
}
int rootvalue = root.val;
ret.add(rootvalue);
if(root.right != null){
inorderTraversal(root.right ,ret);
}
}
3.後序遍歷
public void postorderTraversal(TreeNode root,ArrayList<Integer> ret){
if(root.left != null){
inorderTraversal(root.left,ret);
}
if(root.right != null){
inorderTraversal(root.right,ret);
}
int rootvalue = root.val;
ret.add(rootvalue);
}
三.二叉樹的非遞迴遍歷
非遞迴遍歷的先序和中序遍歷都是用棧實現。
1.先序遍歷
二叉樹的先序遍歷其實就是深度遍歷,如圖所示:
用棧來實現。首先是將所有節點的左子樹的元素全部都進棧,退出迴圈之後,先訪問樹的最左邊的一個節點,也就是棧頂元素,並將它pop,然後將其右子樹入棧。
public ArrayList<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(root == null)return list;
Stack<TreeNode> S = new Stack<TreeNode>();
TreeNode p = root;
while(p != null || !S.empty()){
while(p != null){
S.push(p);
list.add(p.val);
p = p.left;
}
p = S.pop();
p = p.right;
}
return list;
}
2. 中序遍歷
同樣用棧來實現。它與先序遍歷的區別是,先序是入棧的時候訪問節點的value,而中序遍歷是出棧的時候,訪問節點的value。
public ArrayList<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(root == null)return list;
Stack<TreeNode> S = new Stack<TreeNode>();
TreeNode p = root;
while(p!=null || !S.empty()){
while(p!=null){
S.push(p);
p = p.left;
}
p = S.pop();
list.add(p.val);
p = p.right;
}
return list;
}
3. 後序遍歷
後序遍歷是非遞迴遍歷演算法中最難理解的。它需要設定一個標記位,表明這棵子樹已訪問過。
四.二叉樹的層次遍歷
二叉樹的層次遍歷,用佇列實現。
Leetcode-102的程式碼如下:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int> > ret;
if(root == NULL)
{
return ret;
}
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
int size = q.size();
vector<int> level;
for(int i=0;i<size;++i)
{
TreeNode* node = q.front();
level.push_back(node->val);
q.pop();
if(node->left)
{
q.push(node->left);
}
if(node->right)
{
q.push(node->right);
}
}
ret.push_back(level);
}
return ret;
}