码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树操作

时间:2015-03-13 16:23:09      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

问题0:      二叉树的非递归遍历方法

问题1:  判断一颗二叉树是否为二叉查找树.

问题2:  判断两个二叉树是否相同

问题3:      判断一棵树是否为平衡树

问题4:      寻找二叉树的最大和最短简单路径长度

问题5:      二叉树上简单路径的长度问题

 

 

 

解答0:

  [0.1]前序.使用栈,访问节点后先压入右儿子,再压入左儿子即可.

 1 vector<int> preorderTraversal(TreeNode *root){
 2     stack<TreeNode*> st;
 3     st.push(root);
 4     vector<int> res;
 5     
 6     TreeNode *curr;
 7     while(!st.empty()){
 8         curr = st.top();
 9         st.pop();
10 
11         if(curr){
12             res.push_back(curr->val);
13             st.push(curr->right);
14             st.push(curr->left);
15         }
16     }
17 
18     return res;
19 }

  [0.2]中序遍历.使用一个栈,将访问过的节点压入栈中.

 1 vector<int> inorderTraversal(TreeNode *root){
 2     stack<TreeNode*> st;
 3     vector<int> res;
 4 
 5     TreeNode *curr=root,*top;
 6     while(!st.empty() || curr){
 7         if(curr){
 8             st.push(curr);
 9             curr = curr->left;
10         }else{
11             curr = st.top();
12             st.pop();
13             res.push_back(curr->val);
14             curr = curr->right;
15         }
16     }
17 
18     return res;
19 }

  [0.3]

  方法1.后序遍历.访问左儿子前记录本节点,当再次取出节点时,存在其右儿子有没有被访问过的问题.通过记录前驱节点来辅助判断(前驱节点只在特定地点才更新).

 1     vector<int> postorderTraversal(TreeNode *root) {
 2         stack<TreeNode*> st;
 3         vector<int> res;
 4     
 5         TreeNode *curr=root,*prev=root,*top;
 6         while(!st.empty() || curr){
 7             if(curr){
 8                 st.push(curr);
 9                 curr = curr->left;
10             }else{
11                 curr = st.top();
12     
13                 if(prev==curr->right || curr->right==NULL){
14                     st.pop();
15     
16                     res.push_back(curr->val);
17                     prev = curr;
18                     curr = NULL;
19                 }else{
20                     curr = curr->right;
21                 }
22             }
23         }
24         return res;
25     }

  方法2:使用两个栈,一个记录TreeNode*,另一个记录这个节点所对应的剩余访问次数.

       当剩余访问次数为2时,将剩余次数减少为1,并访问其左儿子;

     当剩余访问次数为1时,将剩余次数减少为0,并访问其右儿子;

       当剩余访问次数为0时,访问本节点.

   [0.4]层次遍历. 使用队列.

 

解答1:

  [1.1]首先中序遍历记录节点,然后判断整个记录是否递增.

 1     void inorder(TreeNode *root, vector<int>& v){
 2         if(root){
 3             inorder(root->left,v);
 4             v.push_back(root->val);
 5             inorder(root->right,v);
 6         }
 7     }
 8     
 9     bool isAscend(vector<int>& v){
10         int len = v.size();
11         int i=0;
12         while(i<len-1){
13             if(v[i] >= v[i+1])
14                 return false;
15             i++;
16         }
17         return true;
18     }
19 
20     bool isValidBST(TreeNode *root) {
21         vector<int> v;
22         inorder(root,v);
23     
24         return isAscend(v);
25     }

   [1.2].通过观察可以发现, 方法[1.1]的比较过程就是将每个节点与其前驱节点的值作比较.那么这个比较操作能放在深搜的过程中完成吗? 

 1     bool isValidBST(TreeNode *root) {
 2         TreeNode *curr = root,*prev = NULL;
 3         stack<TreeNode*> st; 
 4     
 5         while(!st.empty() || curr){
 6             if(curr){
 7                 st.push(curr);
 8                 curr = curr->left;
 9             }else{
10                 curr = st.top();
11                 st.pop();
12                 if(prev){
13                     if(prev->val >= curr->val)
14                         return false;
15                 }
16                 prev = curr;
17                 curr = curr->right;
18             }
19         }
20     
21         return true;
22     }

  [1.3]使用子树中节点的左右边界来辅助进行判断.

 1     bool err;
 2 
 3     pair<int, int> dfs(TreeNode *t){
 4         pair<int, int> l, r;
 5         int lbound = t->val, rbound = t->val; // 节点t的子树中节点的左右权值边界
 6         if (t->left){
 7             l = dfs(t->left);
 8             if (l.second >= t->val) err = true;
 9             lbound = l.first;//左边界为左子树的左边界
10         }
11         if (t->right){
12             r = dfs(t->right);
13             if (r.first <= t->val) err = true;
14             rbound = r.second;//右边界为右子树的右边界
15         }
16         return make_pair(lbound, rbound);
17     }
18 
19     bool isValidBST(TreeNode *root) {
20         if (root == NULL) return true;
21         err = false;
22         dfs(root);
23         return !err;
24     }

 

解答2:

  [2.1]可通过同步的遍历来解决.

1 bool isSameTree(TreeNode *p,TreeNode *q){
2     if(p==NULL && q==NULL)
3         return true;
4     return (p && q && p->val==q->val && isSameTree(p->left,q->left) && isSameTree(p->right,q->right));
5 }

 

解答3:

  [3.1]递归方法

 1     int check(TreeNode *root,bool& flag){
 2         int l = 0,r = 0;
 3         if(flag && root && root->left)
 4             l = check(root->left,flag) + 1;
 5         if(flag && root && root->right)
 6             r = check(root->right,flag) + 1;
 7         if(flag)
 8             flag = (abs(l-r)<=1);
 9         return l>r?l:r;
10     }
11 
12     bool isBalanced(TreeNode *root){
13         bool flag = true;
14         check(root,flag);
15         return flag;
16     }

  [3.2]迭代方法

 

解答4: 

 1 int maxDepth(TreeNode *root){
 2         if(root==NULL)
 3             return 0;
 4         return max(maxDepth(root->left),maxDepth(root->right)) + 1;
 5 } 
 6 
 7 int minDepth(TreeNode *root){
 8     if(root==NULL)
 9         return 0;
10     if(root->left==NULL && root->right==NULL)
11         return 1;
12     if(root->left==NULL)
13         return minDepth(root->right)+1;
14     else if(root->right==NULL)
15         return minDepth(root->left)+1;
16     else
17         return min(minDepth(root->left),minDepth(root->right))+1;
18 }

 

解答5:

  检测特定长度的存在性.

 1 bool hasPathSum(TreeNode *root,int sum){
 2     if(root==NULL)
 3         return false;
 4     if(root->left==NULL && root->right==NULL)
 5         return sum==root->val;
 6     if(root->left && hasPathSum(root->left,sum-root->val))
 7         return true;
 8     if(root->right && hasPathSum(root->right,sum-root->val))
 9         return true;
10     return false;
11 }    

  记录特定长度的路径

 1 void  dfs(TreeNode *root,int sum,vector<int> path,vector<vector<int> >& res){
 2     if(root==NULL){
 3         return ;
 4     }
 5     if(root->left==NULL&&root->right==NULL){
 6         if(sum==root->val){
 7             path.push_back(root->val);
 8             res.push_back(path);
 9         }
10         return;
11     }
12     path.push_back(root->val);
13     dfs(root->left,sum-root->val,path,res);
14     dfs(root->right,sum-root->val,path,res);
15     path.pop_back();
16 }
17 
18 vector<vector<int> > pathSum(TreeNode *root, int sum) {
19     vector<vector<int> > res;
20     vector<int> path;
21     dfs(root,sum,path,res);
22     return res;
23 }

 

  

参考


 

  lycc的github代码

二叉树操作

标签:

原文地址:http://www.cnblogs.com/carlsama/p/4154424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!