面试题二叉树相关问题总结
来源:互联网 发布:征服者rd88升级软件 编辑:程序博客网 时间:2024/05/16 15:50
二叉树中的面试题比较常见的题型大概有下面几个:创建一颗二叉树(先序,中序,后序)、遍历一颗二叉树(先序,中序,后序和层次遍历)、求二叉树中叶子节点的个数、求二叉树的高度、求二叉树中两个节点的最近公共祖先、打印和为某一值的全部路径、求某一节点是否在一个树中等等。
再详细的说这些面试题之前,不妨先看一下几种常见的二叉树:
完全二叉树:若二叉树的高度是h,除第h层之外,其他(1~h-1)层的节点数都达到了最大个数,并且第h层的节点都连续的集中在最左边。实际上,完全二叉树和堆联系比较紧密~~~
满二叉树:除最后一层外,每一层上的所有节点都有两个子节点,最后一层都是叶子节点。
哈夫曼树:这是一种带权路径长度最短的树。哈夫曼编码就是哈夫曼树的应用。
平衡二叉树:所谓平衡二叉树指的是,所有的左右两个子树的高度差的绝对值不超过 1。
红黑树:红黑树是每个节点都带颜色的树,节点颜色或是红色或是黑色,红黑树是一种查找树。红黑树有一个重要的性质,从根节点到叶子节点的最长的路径不多于最短的路径的长度的两倍。对于红黑树,插入,删除,查找的复杂度都是O(log N)。
首先给定统一二叉树的数据结构定义:
struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}};
题目1:操作给定的二叉树,将其变换为源二叉树的镜像。
void Mirror(TreeNode *pRoot) { if(!pRoot) return; TreeNode *temp=pRoot->left; pRoot->left=pRoot->right; pRoot->right=temp; Mirror(pRoot->left); Mirror(pRoot->right); }
思路:借助队列实现。每次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到一个队列的结尾。接下来到队列的头部取出最早进入队列的点,重复前面的打印操作,直到队列中所有的结点都被打印出来。
vector<int> PrintFromTopToBottom(TreeNode *root) { vector<int> r; if(!root) return r; deque <TreeNode *> q; q.push_back(root); while(!q.empty()) { TreeNode *temp=q.front(); q.pop_front(); r.push_back(temp->val); if(temp->left) q.push_back(temp->left); if(temp->right) q.push_back(temp->right); } return r; }
题目3:二叉树的深度:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
int TreeDepth(TreeNode* pRoot) { if(pRoot==NULL) return 0; int Left=TreeDepth(pRoot->left); int Right=TreeDepth(pRoot->right); return Left>Right?Left+1:Right+1; }
题目4:输入一棵二叉树,判断该二叉树是否是平衡二叉树。
int GetDepth(TreeNode* pRoot) { if(pRoot==NULL) return 0; else return 1+max(GetDepth(pRoot->left),GetDepth(pRoot->right)); } bool IsBalanced_Solution(TreeNode* pRoot) { if(pRoot==NULL) return true; int Left=GetDepth(pRoot->left); int Right=GetDepth(pRoot->right); int diff=Left-Right; if(diff<-1||diff>1) return false; else return IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right); }
bool isSymmetrical(TreeNode* pRoot) { if(pRoot==NULL) return true; else return isSymmetrical1(pRoot->left,pRoot->right); } bool isSymmetrical1(TreeNode *pRoot1,TreeNode* pRoot2) { if(pRoot1==NULL&&pRoot2==NULL) return true; if(pRoot1==NULL||pRoot2==NULL) return false; if(pRoot1->val==pRoot2->val) return isSymmetrical1(pRoot1->left,pRoot2->right)&&isSymmetrical1(pRoot1->right,pRoot2->left); return false; }
题目6:按照之字形打印二叉树,请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
vector<vector<int> > Print(TreeNode* pRoot) { vector<vector<int>>result; if(pRoot==NULL) return result; stack <TreeNode*> stack1,stack2; //stack1存储奇数层 stack2存储偶数层 stack1.push(pRoot); while(!stack1.empty()||!stack2.empty()) { vector<int> level; if(!stack1.empty()) { while(!stack1.empty()) { TreeNode *temp=stack1.top(); level.push_back(temp->val); if(temp->left) stack2.push(temp->left); if(temp->right) stack2.push(temp->right); stack1.pop(); } } else { while(!stack2.empty()) { TreeNode*temp=stack2.top(); level.push_back(temp->val); if(temp->right) stack1.push(temp->right); if(temp->left) stack1.push(temp->left); stack2.pop(); } } result.push_back(level); } return result; }
题目7:把二叉树打印成多行,从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
vector<vector<int> > Print(TreeNode* pRoot) { vector<vector<int> > result; if(!pRoot) return result; queue<TreeNode*>nodes; vector<int>line; nodes.push(pRoot); int currLevel=1; //记录nodes中存的当前层的结点个数 int nextLevel=0; //记录nodes中存的下一层的结点个数 while(!nodes.empty()) { TreeNode *temp=nodes.front(); if(temp->left) { nodes.push(temp->left); nextLevel++; } if(temp->right) { nodes.push(temp->right); nextLevel++; } line.push_back(temp->val); currLevel--; nodes.pop(); if(0==currLevel) //当当前层已经处理完了,把当前line输出到结果result中,完成一行 { result.push_back(line); line.clear(); currLevel=nextLevel; nextLevel=0; } } if(!line.empty()) result.push_back(line); return result; }
题目8:二叉搜索树的第k个结点,给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
TreeNode* KthNode(TreeNode* pRoot, unsigned int k) { if(!pRoot||k<=0) return NULL; //中序遍历就是二叉搜索树的排序 vector<TreeNode *> array; InOrder(pRoot,array); if(k>array.size()) return NULL; return array[k-1]; } void InOrder(TreeNode *pRoot,vector<TreeNode *>&Order) { if(!pRoot) return; InOrder(pRoot->left,Order); Order.push_back(pRoot); InOrder(pRoot->right,Order); }
题目9:二叉搜索树的后序遍历序列,输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
bool VerifySeqenceOfBST(int *seqence,int length){if(seqence==NULL||length<=0)return false;int root=seqence[length-1];//在二叉搜素树中左子树的结点小于根结点int i=0;for(;i<length-1;i++){if(seqence[i]>root)break;}//在二叉搜素树中右子树的结点大于根结点for(int j=i;j<length-1;j++){if(seqence[j]<root)return false;}//判断左子树是不是二叉搜索树bool left=true;if(i>0)left=VerifySeqenceOfBST(seqence,i);//判断右子树是不是二叉搜索树bool right=true;if(i<length-1)right=VerifySeqenceOfBST(seqence+i,length-i-1);return left&&right;}
题目10:树的子结构,输入两颗二叉树A,B,判断B是不是A的子结构。
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) { bool r=false; if(pRoot1!=NULL&&pRoot2!=NULL) { if(pRoot1->val==pRoot2->val) r=DoesTree1HaveTree2(pRoot1,pRoot2); if(!r) r=HasSubtree(pRoot1->left,pRoot2); if(!r) r=HasSubtree(pRoot1->right,pRoot2); } return r; } bool DoesTree1HaveTree2(TreeNode *pRoot1,TreeNode *pRoot2) { if(pRoot2==NULL) return true; if(pRoot1==NULL) return false; if(pRoot1->val!=pRoot2->val) return false; return DoesTree1HaveTree2(pRoot1->left,pRoot2->left)&&DoesTree1HaveTree2(pRoot1->right,pRoot2->right); }
0 0
- 面试题二叉树相关问题总结
- 二叉树相关面试题总结
- 面试题(二叉树相关)
- 面试题(二叉树相关)
- 二叉树相关面试题
- 【面试题】二叉树相关
- 面试题精选(83):二叉树相关的问题
- 二叉树面试题总结
- 二叉树相关的面试题
- 二叉树相关面试题集锦
- 二叉树相关面试题及代码
- 二叉树的相关面试题
- 和二叉树相关的面试题
- 二叉树相关的面试题<一>
- 二叉树的相关面试题<二>
- 二叉树以及相关的面试题
- 二叉树相关面试题汇总
- 【数据结构】二叉树面试题总结
- [leetcode]51 Delete Node in a Linked List
- 如果获取apk的总方法数
- LINUX重启MYSQL的命令
- [unity3d]手游资源热更新策略探讨
- C# 抽象类和抽象方法详解
- 面试题二叉树相关问题总结
- Linux 中open系统调用实现原理 2012-11-29 23:03:48 http://blog.chinaunix.net/uid-25968088-id-3426026.html
- 英文简历
- 当程序崩溃的时候怎么办 Part-2
- 安卓布局屏幕适配问题解决办法
- 网络流增广路入门很好的文章
- [刷题]Sqrt(x)
- FreeMarker标签与使用
- 1093. Count PAT's (25)