树的相关题目
2015-10-30 23:45
344 查看
五.树
5.1二叉树的遍历 分别写出递归和迭代版本*
5.1.1.先序优先遍历 Binary Tree Preorder Traversal
递归版本class Solution { public: vector<int> preorderTraversal(TreeNode *root) { vector<int > ret; helper(ret,root); return ret; } void helper(vector<int>&ret , TreeNode* root){ if(root==NULL)return ; else ret.push_back(root->val); if(root->left!=NULL) helper(ret,root->left); if(root->right!=NULL) helper(ret,root->right); } };迭代版本
class Solution { public: vector<int> preorderTraversal(TreeNode *root) { //用栈来实现先序优先遍历 vector<int > ret; if(root==NULL) return ret; stack<TreeNode* > mystack; mystack.push(root); TreeNode* temp; while(!mystack.empty()){ temp= mystack.top(); mystack.pop(); ret.push_back(temp->val); //先把右子节点入栈 if(temp->right!=NULL) mystack.push(temp->right); if(temp->left!= NULL) mystack.push(temp->left); } return ret; } };
5.1.2中序优先遍历
递归版本class Solution { public: vector<int> inorderTraversal(TreeNode *root) { vector<int > ret; helper(ret, root); return ret; } void helper(vector<int>&ret ,TreeNode* root){ if(root==NULL) return; if(root->left!=NULL) helper(ret,root->left); ret.push_back(root->val); if(root->right!=NULL) helper(ret,root->right); } };迭代版本
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> ret; if(root==NULL) return ret; stack<TreeNode* > mystack; TreeNode* p=root; while(p!=NULL){ mystack.push(p); p=p->left; } while(!mystack.empty()){ TreeNode * temp = mystack.top(); mystack.pop(); ret.push_back(temp->val); if(temp->right!=NULL){ //如果出栈的节点右子节点不空,这将右子节点的左子节点入入栈,直到没有左子节点 p=temp->right; while(p!=NULL){ mystack.push(p); p=p->left; } } } return ret; } };
5.1.3 后序优先遍历
思考:步骤:1.3.注意:5.1.4 输出二叉树的每层的数。 leetcode 102
思考:递归版本,相当于广度优先遍历,用一个参数来表明大小步骤:1.3.注意:class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int> > ret; if(root==NULL) return ret; helper(root, ret,0); return ret; } void helper(TreeNode* root, vector<vector<int> > &ret,int level){ if(!root)return ; if(level+1>ret.size() ) //注意 level>ret.size()-1 unsigned int 与 int 运算时, int 会被转换为unit ret.push_back(vector<int>()); ret[level].push_back(root->val); if(root->left!=NULL) helper(root->left, ret ,level+1); if(root->right!=NULL) helper(root->right, ret,level+1); } };
class Solution { public: vector<vector<int> > levelOrder(TreeNode* root) { vector<vector<int> > ret; if(root==NULL) return ret; vector<TreeNode* > layer; layer.push_back(root); while(!layer.empty()){ vector<int> temp; vector<TreeNode* > deq; TreeNode* t; for(int i=0 ;i<layer.size();i++){ t= layer[i]; temp.push_back(t->val); if(t->left) 154e4 deq.push_back(t->left); if(t->right) deq.push_back(t->right); } ret.push_back(temp); layer=deq; } return ret; } }; class Solution { public: vector<vector<int> > levelOrder(TreeNode* root) { vector<vector<int> > ret; if(root==NULL) return ret; deque<TreeNode* > deq1; deque<TreeNode* > deq2; deq1.push_back(root); while(!deq1.empty()) { vector<int> temp; TreeNode* t; while(!deq1.empty()){ t=deq1.front(); deq1.pop_front(); temp.push_back(t->val); if(t->left) deq2.push_back(t->left); if(t->right) deq2.push_back(t->right); } ret.push_back(temp); swap(deq1,deq2); //这个知识交换指向的空间,并没有复制操作 } return ret; } };
5.1.5 返回二叉树每层最右边的节点
结果同上://只不过是 //result[i]=root->val; 不断根新最后一个数存放的数组 class Solution { public: vector<int> rightSideView(TreeNode* root) { vector<int> ret; vector<TreeNode* > layer; if(root==NULL) return ret; layer.push_back(root); int level=0; while(!layer.empty()){ vector<TreeNode* > temp; for(int i=0;i<layer.size();i++){ TreeNode* p=layer[i]; if(level+1>ret.size()) ret.resize(level+1); ret[level]=layer[i]->val; if(p->left!=NULL) temp.push_back(p->left); if(p->right!=NULL) temp.push_back(p->right); } layer=temp; level++; } return ret; } };
5.2树的判定
5.2.1 两个树是否相等
思考:Given two binary trees, write a function to check if they are equal or not.Two binary trees are considered equal if they are structurally identical and the nodes have the same value.步骤:1.3.注意:class Solution { /* 1.如果其中之一NULL,则该判断另一个子树是否为NULL * 2.当前两值是否相等,递归判定其左右子树 */ public: bool isSameTree(TreeNode* p, TreeNode* q) { if(p==NULL) return q==NULL; if(q==NULL) return p==NULL; return p->val==q->val&&isSameTree(p->left,q->left)&&isSameTree(p->right,q->right); } }; //非递归版本 借用栈来实现 class Solution { public: bool isSameTree(TreeNode* p, TreeNode* q) { if(p==NULL)return q==NULL; if(q==NULL) return p==NULL; stack<TreeNode* > stk; stk.push(q); stk.push(p); while(!stk.empty()) { p=stk.top(); stk.pop(); q=stk.top(); stk.pop(); if(p==NULL&&q==NULL) continue; if(p==NULL||q==NULL) return false; if(p->val!=q->val) return false; stk.push(q->right); stk.push(p->right); stk.push(q->left); stk.push(p->left); } return true; } };
5.2.2 判断树是否对称
- **思考**: - **步骤**: * 1. * 2. * * * * 3. - **注意**:
class Solution { public: bool isSymmetric(TreeNode *root) { if(root==NULL) return true; return helper(root->left,root->right); } bool helper(TreeNode * p, TreeNode * q){ if(p==NULL) return q==NULL; if(q==NULL) return p==NULL; return p->val==q->val&&helper(p->left,q->right)&&helper(p->right,q->left); } }; // 非递归版本 class Solution { public: bool isSymmetric(TreeNode* root) { if(!root) return true; return isSymmetric(root->left, root->right); } bool isSymmetric(TreeNode* p, TreeNode* q) { if(!p&&!q) return true; stack<TreeNode* > stk; stk.push(q); stk.push(p); while(!stk.empty()){ p=stk.top(); stk.pop(); q=stk.top(); stk.pop(); if(!p&&!q) continue; if(!p||!q) return false; if(p->val!=q->val) return false; stk.push(q->right); stk.push(p->left); stk.push(q->left); stk.push(p->right); } return true; } };
5.2.3 二叉树是否平衡 Validate Binary Search Tree
Given a binary tree, determine if it is height-balanced.For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.class Solution { public: bool isBalanced(TreeNode *root) { int height = getHeight(root); if(height==-1) return false; return true; } int getHeight(TreeNode * root) { if(root==NULL) return 0; int left = getHeight(root->left); int right =getHeight(root->right); if(left==-1||right==-1||abs(left-right)>1) return -1; return max(left,right)+1; } };
5.2.4 二叉搜索树是否合法 Validate Binary Search Tree
Description :Given a binary tree, determine if it is a valid binary search tree (BST).Assume a BST is defined as follows:The left subtree of a node contains only nodes with keys less than the node’s key.The right subtree of a node contains only nodes with keys greater than the node’s key.Both the left and right subtrees must also be binary search trees.思考: 中序遍历,当前值大于中序遍历的last 值,全部成立即可,那么怎么获取中序遍历的最后一个之呢,使用引用class Solution { public: bool isValidBST(TreeNode* root) { if(root==NULL) return true; bool mark=true; int last=0; help(root,mark,last); } bool help(TreeNode* root, bool& first, int &last){ if(root==NULL) return true; bool templeft = help(root->left,first,last); // 遍历左子树,同时返回遍历的最后一个值 if(!templeft) return false; // 左子树不合法,则返回false if(first){ // 当前节点是第一个值,这不比较 first=false; } else if(last>=root->val) // 不是第一个节点则比较 return false; last = root->val; //更新已遍历的最后一个值 return help(root->right,first,last); // 遍历右子树 } };
5.3 树的路径与深度
5.3.1 二叉树的最小深度 letcode 111 Minimum Depth of Binary Tree
Description:Given a binary tree, find its minimum depth.The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.思考:1.二叉树的广度优先遍历,利用队列,直到找到一个叶子节点,则停止循环。2.递归的解法: 只有叶子节点才算深度,如果为叶子节点,则返回1,如果非叶子节点,但其中左右子树为NULL,则返回另一个为空的子树的深度,若左右子树都不为NULL,则返回两者中小的+1;class Solution { public: int minDepth(TreeNode* root) { if(root==NULL) return 0; if(root->left==NULL&&root->right==NULL) return 1; if(root->left==NULL)return minDepth(root->right)+1; if(root->right==NULL) return minDepth(root->left)+1; return min(minDepth(root->left),minDepth(root->right))+1; } }; class Solution { public: int minDepth(TreeNode* root) { if(root==NULL)return 0; vector<TreeNode* > vec; vec.push_back(root); int ret=0; while(!vec.empty()){ ret++; vector<TreeNode* >temp; for(int i=0;i<vec.size();i++){ if(vec[i]->left!=NULL) temp.push_back(vec[i]->left); if(vec[i]->right!=NULL) temp.push_back(vec[i]->right); if(vec[i]->left==NULL&&vec[i]->right==NULL) return ret; } vec=temp; } return ret; } };
5.3.2 二叉树的最大高度 leetcode 104
class Solution { public: int maxDepth(TreeNode* root) { if(root==NULL)return 0; return max(maxDepth(root->left),maxDepth(root->right))+1; } };
5.3.3 是否存在和为定值的路径 leetcode 112
Description:Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.For example:Given the below binary tree and sum = 22,5/ \4 8/ / \11 13 4/ \ \7 2 1return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.class Solution { public: bool hasPathSum(TreeNode *root, int sum) { if(root==NULL) return false; if(root->left==NULL&&root->right==NULL) { if(sum==root->val) return true; else return false; } return hasPathSum(root->left,sum-root->val)|| hasPathSum(root->right,sum-root->val); } };
5.3.4 Binary Tree Maximum Path Sum leetcode 124
class Solution { public: int maxPathSum(TreeNode* root) { if(root==NULL) return 0; int m=root->val; getSum(root,m); return m; } int getSum(TreeNode * root ,int &m){ if(root==NULL) return 0; int left = getSum(root->left,m); int right =getSum(root->right,m); int ret =max(max(left ,right),0)+root->val; //经过当前节点的长路径,左,右,仅有当前节点 m=max(max(ret,m),left+right+root->val); // 横跨当前节点的最长路径 return ret; } };
5.4 树的构造与变换
5.4.1 Flatten Binary Tree to Linked List
实际上的先序遍历变为链表class Solution {public:void flatten(TreeNode* root) {if(root==NULL) return ;stack<TreeNode* > stk;stk.push(root);TreeNode te(0);TreeNode* dummy=&te;TreeNode* tail=dummy;TreeNode * current;while(!stk.empty()){current =stk.top();stk.pop();if(current->right)stk.push(current->right);if(current->left)stk.push(current->left);tail->right=current;tail=current;tail->left =NULL;tail->right =NULL;}root=dummy->right;}};
5.4.2 Populating Next Right Pointers in Each Node
- **思考**:1.立即想到使用广搜,记录每一层的链表尾节点,但需要有一个 vector<TreeLinkNode* > 来记录每一层的尾节点,不符合题目的常数空间的要求2. 递归调用,对每一层已经链接好的链表,遍历其中每个节点,操纵他们的子节点步骤:1.3.注意:
// 采用广度优先遍历的思想class Solution {public:void connect(TreeLinkNode *root) {vector<TreeLinkNode* > ret;helper(root, ret,0);}void helper(TreeLinkNode* root , vector<TreeLinkNode* > &ret, int level){if(root==NULL) return;if(level+1>ret.size())ret.push_back(root);else{ret[level]->next=root;ret[level]=root;}helper(root->left ,ret,level+1);helper(root->right, ret,level+1);}};
class Solution {public:void connect(TreeLinkNode *root) {if(root==NULL||root->left==NULL) return;TreeLinkNode* p=root;TreeLinkNode* tail=root->left; //下一层链表的队尾while(p!=NULL){if(p==root){p->left->next =p->right;}else {tail->next=p->left;p->left->next =p->right;}tail =p->right;p=p->next;}connect(root->left);}};
5.4.3 Populating Next Right Pointers in Each Node II
class Solution {public:void connect(TreeLinkNode *root) {vector<TreeLinkNode* > ret;helper(root, ret,0);}void helper(TreeLinkNode* root , vector<TreeLinkNode* > &ret, int level){if(root==NULL) return;if(level+1>ret.size())ret.push_back(root);else{ret[level]->next=root;ret[level]=root;}helper(root->left ,ret,level+1);helper(root->right, ret,level+1);}};//递归版本class Solution {public:void connect(TreeLinkNode *root) {if(root==NULL) return;TreeLinkNode* p=root;TreeLinkNode temp(0);TreeLinkNode* tail=&temp;while(p!=NULL){if(p->left==NULL&&p->right==NULL){p=p->next;continue;}else if(p->left!=NULL&&p->right!=NULL){tail->next =p->left;p->left->next=p->right;tail=p->right;}else {tail->next = (p->left!=NULL)?p->left:p->right;tail=tail->next;}p=p->next;}connect(temp.next);}};//迭代版本class Solution {public:void connect(TreeLinkNode *root) {if(root==NULL) return;TreeLinkNode* p;// 迭代版本while(root!=NULL){TreeLinkNode temp(0);TreeLinkNode* tail=&temp;p=root;while(p!=NULL){if(p->left==NULL&&p->right==NULL){p=p->next;continue;}else if(p->left!=NULL&&p->right!=NULL){tail->next =p->left;p->left->next=p->right;tail=p->right;}else {tail->next = (p->left!=NULL)?p->left:p->right;tail=tail->next;}p=p->next;}root=temp.next;}}};
5.4.4 Binary Search Tree Iterator
维护一个结构从开头每次调用next,返回中序遍历下一个节点思考:用栈s保存每个根节点——一条路径cur表示当前要考虑的根节点cur 一直往左走,走过的节点入栈最后一个出栈(无左子树),访问它,它就是下一个要考虑的节点, cur = s.top()cur = cur->right;注意缓存,如果调用两次hasNext不应该改变结果个人思考: 实际上是中序遍历的迭代版本/*** Definition for binary tree* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class BSTIterator {public:BSTIterator(TreeNode *root) {while(root!=NULL){mystack.push(root);root=root->left;}}/** @return whether we have a next smallest number */bool hasNext() {return !mystack.empty();}/** @return the next smallest number */int next() {TreeNode* temp=mystack.top();mystack.pop();TreeNode* p;if(temp->right!=NULL){p=temp->right;while(p!=NULL){mystack.push(p);p=p->left;}}return temp->val;}private :stack<TreeNode* > mystack;};/*** Your BSTIterator will be called like this:* BSTIterator i = BSTIterator(root);* while (i.hasNext()) cout << i.next();*/
5.4.5 Construct Binary Tree from Preorder and Inorder Traversal Leetcode 105
给定二叉树前、中序遍历,构造二叉树 (Leetcode 105)分析:前序遍历序列第一个是根节点x从中序遍历序列中找到根节点x中序遍历中x的左边序列对应等长的前序遍历序列左子树中序遍历中x的右边序列对应等长的前序遍历序列右子树class Solution {public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {return helper(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);}TreeNode* helper(vector<int>& preorder, vector<int>& inorder ,int pl,int ph ,int il,int ih){if(pl>ph) return NULL;TreeNode * root = new TreeNode(preorder[pl]);int i=il;for( ;i<=ih;i++){if(inorder[i]==preorder[pl])break;}int leftlen=i-il;int rightlen=ih-i;root->left = helper(preorder,inorder,pl+1,pl+leftlen,il,i-1);root->right =helper(preorder,inorder,pl+leftlen+1,ph,i+1,ih);return root;}};
5.4.6 Construct Binary Tree from Inorder and Postorder Traversal leetcode 106
定二叉树后、中序遍历,构造二叉树后序遍历序列最后一个是根节点x从中序遍历序列中找到根节点x中序遍历中x的左边序列对应等长的后序遍历序列左子树中序遍历中x的右边序列对应等长的后序遍历序列右子树class Solution {public:TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {if(inorder.size()==0) return NULL;int N = inorder.size();TreeNode * ret= helper(inorder, postorder, 0,N-1 ,0,N-1)return ret;}TreeNode * helper(vector<int> &inorder, vector<int> &postorder, int instart ,int inend ,int postart,int poend) {if(instart==inend) return new TreeNode(inorder[instart]);if(instart>inend) return NULL;int last = postorder[poend];TreeNode * ret = new TreeNode(last);int mid=instart;for(int i=instart ;i<=inend ;i++)if(inorder[i]==last){mid= i;break;}ret->left= helper(inorder,postorder, instart,mid-1,postart,postart+(mid-1-instart));ret->right = helper(inorder,postorder, mid+1,inend,postart+(mid-1-instart)+1,poend-1);return ret;}};
5.4.7 Convert Sorted Array to Binary Search Tree leetcode108
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.class Solution {public:TreeNode* sortedArrayToBST(vector<int>& nums) {return helper(nums,0,nums.size()-1);}TreeNode* helper(vector<int>& nums, int start,int end){if(start>end) return NULL;int mid =start+(end-start)/2;TreeNode* root=new TreeNode(nums[mid]);root->left=helper(nums,start,mid-1);root->right =helper(nums,mid+1,end);return root;}};
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- C++非递归队列实现二叉树的广度优先遍历
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#非递归先序遍历二叉树实例
- C++非递归建立二叉树实例
- C语言实现找出二叉树中某个值的所有路径的方法
- C++实现二叉树遍历序列的求解方法
- C语言实现二叉树遍历的迭代算法
- 用C语言判断一个二叉树是否为另一个的子结构
- C++实现二叉树非递归遍历方法实例总结
- C++二叉树结构的建立与基本操作
- 深入遍历二叉树的各种操作详解(非递归遍历)
- JavaScript数据结构和算法之二叉树详解
- java使用归并删除法删除二叉树中节点的方法
- Java中二叉树数据结构的实现示例
- python数据结构之二叉树的建立实例
- python数据结构树和二叉树简介
- python数据结构之二叉树的统计与转换实例