题目列表:
1. 求二叉树的深度->树的最小深度->判断二叉树是不是完全二叉树
2.求二叉树中的节点个数->求二叉树中叶子节点的个数->求二叉树第K层的节点个数
3. 前序遍历,中序遍历,后序遍历
4.分层遍历二叉树(按层次从上往下,从左往右打印二叉树)
5. 求二叉树的镜像->对称二叉树
6. 判断两棵树是否相等->一棵树是否是另一棵树的子树->一棵树是否是另一棵树的子结构(定义空树不是任意树的子)
7. 将二叉查找树变为有序的双向链表
8. 求二叉树中两个节点的最低公共祖先节点
9. 求二叉树中节点的最大距离
10. 由前序遍历序列和中序遍历序列重建二叉树
11.之字打印
1
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;
定义树 //
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
/// 求树的深度
int depth(TreeNode* pRoot){
if(!pRoot)
return 0;
return 1+max(depth(pRoot->left),depth(pRoot->right));
}
/// 求树的最小深度
int minDepth(TreeNode *root) {
// write your code here
if(root == NULL)
return false;
if(root->left == NULL) return minDepth(root->right) + 1; //单树的情况
if(root->right == NULL) return minDepth(root->left) + 1;
int leftDepth = minDepth(root->left);
int rightDepth = minDepth(root->right);
return leftDepth < rightDepth ? (leftDepth + 1) : (rightDepth + 1);
}
平衡二叉树 一。定义法 /
bool IsBalanced_Solution(TreeNode* pRoot) {
if(!pRoot)
return true;
int l_depth=depth(pRoot->left);
int r_depth=depth(pRoot->right);
int dif=abs(l_depth-r_depth);
return IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right)&&(dif<=1);
}
平衡二叉树 二 自底向上 better /
int dfsHeight (TreeNode *root) {
if (root == NULL) return 0;
int leftHeight = dfsHeight (root -> left);
if (leftHeight == -1) return -1;
int rightHeight = dfsHeight (root -> right);
if (rightHeight == -1) return -1;
if (abs(leftHeight - rightHeight) > 1) return -1;
return max (leftHeight, rightHeight) + 1;
}
bool isBalanced(TreeNode *root) {
return dfsHeight (root) != -1;
}
2
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
定义树 //
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
/// 节点的个数 //
int GetNodeNum(TreeNode * pRoot)
{
if(pRoot == NULL) // 递归出口
return 0;
return GetNodeNum(pRoot->left) + GetNodeNum(pRoot->right) + 1;
}
叶子节点个数 /
int GetLeafNodeNum(TreeNode * pRoot)
{
if(pRoot == NULL)
return 0;
if(pRoot->left == NULL && pRoot->right == NULL)
return 1;
int numLeft = GetLeafNodeNum(pRoot->left); // 左子树中叶节点的个数
int numRight = GetLeafNodeNum(pRoot->right); // 右子树中叶节点的个数
return (numLeft + numRight);
}
第k层节点个数 /
int GetNodeNumKthLevel(TreeNode * pRoot, int k)
{
if(pRoot == NULL || k < 1)
return 0;
if(k == 1)
return 1;
int numLeft = GetNodeNumKthLevel(pRoot->left, k-1); // 左子树中k-1层的节点个数
int numRight = GetNodeNumKthLevel(pRoot->right, k-1); // 右子树中k-1层的节点个数
return (numLeft + numRight);
}
3
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
定义树 //
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
// 前序遍历PreOrder 中序遍历InOrder 后序遍历PostOrder
void PreOrder(TreeNode* pRoot){
if(pRoot==NULL)
return;
Visit(pRoot); // cout << root->val << " ";
PreOrder(pRoot->left);
// 中序 Visit(pRoot);
PreOrder(pRoot->right);
// 后序 Visit(pRoot);
}
4
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;
定义树 //
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
//广度优先搜索,使用队列实现
void Level(TreeNode* pRoot){
if(pRoot==NULL)
return;
queue<TreeNode *> q; //队列初始化
q.push(pRoot); //将根节点压入队列
while(!q.empty()){
TreeNode* pNode=q.front(); //pNode指向队列的前端
q.pop(); //弹出
Visit(pNode); //访问
if(pNode->left!=NULL) //若左子节点或右子节点不为空,将其压入队列
q.push(pNode->left);
if(pNode->right!=NULL)
q.push(pNode->right);
}
return;
}
5
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
定义树 //
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
/ 镜像 ///
void Mirror(TreeNode *pRoot) {
if(pRoot==NULL)
return;
if((pRoot->left==NULL)&&(pRoot->right==NULL))
return;
TreeNode *tmp;
tmp=pRoot->left;
pRoot->left=pRoot->right;
pRoot->right=tmp;
Mirror(pRoot->left);
Mirror(pRoot->right);
}
// 对称 //
bool isSymmetrical(TreeNode* pRoot)
{
return isSymmetrical(pRoot,pRoot);
}
bool isSymmetrical(TreeNode* pRoot1,TreeNode* pRoot2)
{
if(pRoot1==nullptr&&pRoot2==nullptr)
return true;
if(pRoot1==nullptr||pRoot2==nullptr)
return false;
if(pRoot1->val!=pRoot2->val)
return false;
return isSymmetrical(pRoot1->left,pRoot2->right)&& isSymmetrical(pRoot1->right,pRoot2->left);
}
6
首先自定义结构,根据考题写相应的子模块
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
bool isSameTree(TreeNode *p, TreeNode *q) {
if (p == NULL || q == NULL) return (p == q);
return (p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right));
}
bool isSubtree(TreeNode* s, TreeNode* t) { // t是s的子树?
if(!s) return false;
if (isSame(s,t)) return true;
return isSubtree(s->left,t) || isSubtree(s->right,t);
}
bool dfs(TreeNode * r1, TreeNode * r2){
if(!r2) return true; // r2 小树遍历完就结束
if(!r1) return false;
return ((r1->val == r2->val)&&dfs(r1->left, r2->left) && dfs(r1->right, r2->right));
}
bool isSubstruct(TreeNode* s, TreeNode* t){ // t是s的子结构?
if(!s) return false;
if(!t) return false;
return ( dfs(s,t)) || isSubstruct(s->left, t) || isSubstruct(s->right, t);
}
7
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
定义树 //
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
}; //要记得写 ;
void Convert(TreeNode * pRoot,TreeNode * & pFirstNode, TreeNode * & pLastNode)
{
TreeNode *pFirstLeft, *pLastLeft, * pFirstRight, *pLastRight;
if(pRoot == NULL)
{
pFirstNode = NULL;
pLastNode = NULL;
return;
}
if(pRoot->left == NULL)
{
// 如果左子树为空,对应双向有序链表的第一个节点是根节点
pFirstNode = pRoot;
}
else
{
Convert(pRoot->left, pFirstLeft, pLastLeft);
// 二叉查找树对应双向有序链表的第一个节点就是左子树转换后双向有序链表的第一个节点
pFirstNode = pFirstLeft;
// 将根节点和左子树转换后的双向有序链表的最后一个节点连接
pRoot->left = pLastLeft;
pLastLeft->right = pRoot;
}
if(pRoot->right == NULL)
{
// 对应双向有序链表的最后一个节点是根节点
pLastNode = pRoot;
}
else
{
Convert(pRoot->right, pFirstRight, pLastRight);
// 对应双向有序链表的最后一个节点就是右子树转换后双向有序链表的最后一个节点
pLastNode = pLastRight;
// 将根节点和右子树转换后的双向有序链表的第一个节点连接
pRoot->right = pFirstRight;
pFirstRight->left = pRoot;
}
return;
}
};
8
递归解法:
(1)如果两个节点分别在根节点的左子树和右子树,则返回根节点
(2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
bool FindNode(TreeNode * pRoot, TreeNode * pNode)
{
if(pRoot == NULL || pNode == NULL)
return false;
if(pRoot == pNode)
return true;
bool found = FindNode(pRoot->left, pNode);
if(!found)
found = FindNode(pRoot->right, pNode);
return found;
}
BinaryTreeNode * GetLastCommonParent(TreeNode * pRoot,
TreeNode * pNode1,
TreeNode * pNode2)
{
if(FindNode(pRoot->left, pNode1))
{
if(FindNode(pRoot->right, pNode2))
return pRoot;
else
return GetLastCommonParent(pRoot->left, pNode1, pNode2);
}
else
{
if(FindNode(pRoot->left, pNode2))
return pRoot;
else
return GetLastCommonParent(pRoot->right, pNode1, pNode2);
}
}
9
递归解法:
(1)如果二叉树为空,返回0,同时记录左子树和右子树的深度,都为0
(2)如果二叉树不为空,最大距离要么是左子树中的最大距离,要么是右子树中的最大距离,要么是左子树节点中到根节点的最大距离+右子树节点中到根节点的最大距离,同时记录左子树和右子树节点中到根节点的最大距离。
int GetMaxDistance(TreeNode * pRoot, int & maxLeft, int & maxRight)
{
// maxLeft, 左子树中的节点距离根节点的最远距离
// maxRight, 右子树中的节点距离根节点的最远距离
if(pRoot == NULL)
{
maxLeft = 0;
maxRight = 0;
return 0;
}
int maxLL, maxLR, maxRL, maxRR;
int maxDistLeft, maxDistRight;
if(pRoot->m_pLeft != NULL)
{
maxDistLeft = GetMaxDistance(pRoot->m_pLeft, maxLL, maxLR);
maxLeft = max(maxLL, maxLR) + 1;
}
else
{
maxDistLeft = 0;
maxLeft = 0;
}
if(pRoot->m_pRight != NULL)
{
maxDistRight = GetMaxDistance(pRoot->m_pRight, maxRL, maxRR);
maxRight = max(maxRL, maxRR) + 1;
}
else
{
maxDistRight = 0;
maxRight = 0;
}
return max(max(maxDistLeft, maxDistRight), maxLeft+maxRight);
}
//测试用例
#include <stdlib.h>
#include <stdio.h>
typedef struct Node {
struct Node *pleft; //左孩子
struct Node *pright; //右孩子
char chValue; //该节点的值
int leftMaxValue; //左子树最长距离
int rightMaxValue; //右子树最长距离
}LNode, *BinTree;
void findMaxLen(BinTree root, int *maxLen) {
//遍历到叶子结点,返回
if(root == NULL)
return;
//如果左子树为空,那么该节点左边最长距离为0
if(root->pleft == NULL)
root->leftMaxValue = 0;
//如果右子树为空,那么该节点右边最长距离为0
if(root->pright == NULL)
root->rightMaxValue = 0;
//如果左子树不为空,递归寻找左子树最长距离
if(root->pleft != NULL)
findMaxLen(root->pleft, maxLen);
//如果右子树不为空,递归寻找右子树最长距离
if(root->pright != NULL)
findMaxLen(root->pright, maxLen);
//计算左子树中距离根节点的最长距离
if(root->pleft != NULL) {
if(root->pleft->leftMaxValue > root->pleft->rightMaxValue)
root->leftMaxValue = root->pleft->leftMaxValue + 1;
else
root->leftMaxValue = root->pleft->rightMaxValue + 1;
}
//计算右子树中距离根节点的最长距离
if(root->pright != NULL) {
if(root->pright->leftMaxValue > root->pright->rightMaxValue)
root->rightMaxValue = root->pright->leftMaxValue + 1;
else
root->rightMaxValue = root->pright->rightMaxValue + 1;
}
//更新最长距离
if(root->leftMaxValue + root->rightMaxValue > *maxLen)
*maxLen = root->leftMaxValue + root->rightMaxValue;
}
//创建二叉树
void buildBinTree(BinTree *root)
{
char ch;
scanf("%c", &ch); //输入一个元素
fpurge(stdin);
if(ch == ' ') //若输入的是空格符,表明二叉树为空,置*root为NULL
*root = NULL;
else { //若输入的不是空格符,则将该值赋值给根节点的chValue, 递归建立左子树和右子树
*root = (BinTree)malloc(sizeof(LNode));
(*root)->chValue = ch;
(*root)->leftMaxValue = 0;
(*root)->rightMaxValue = 0;
buildBinTree(&(*root)->pleft);
buildBinTree(&(*root)->pright);
}
}
//销毁二叉树,释放内存
void destroyBinTree(BinTree *root)
{
if(*root != NULL) {
destroyBinTree(&(*root)->pleft);
destroyBinTree(&(*root)->pright);
free(*root);
*root = NULL;
}
}
//前序遍历二叉树
void preOrderTraverse(BinTree root)
{
if(root != NULL) {
preOrderTraverse(root->pleft);
printf("%c", root->chValue);
preOrderTraverse(root->pright);
}
}
int main() {
BinTree root;
buildBinTree(&root);
preOrderTraverse(root);
printf("\n");
int maxLen = 0;
findMaxLen(root, &maxLen);
printf("maxLen = %d\n", maxLen);
destroyBinTree(&root);
}
10
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
};
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
TreeNode* root=reConstructBinaryTree(pre,0,pre.size()-1,vin,0,vin.size()-1);
return root;
}
TreeNode* reConstructBinaryTree(vector<int> pre,int startPre,int endPre,vector<int> vin,int startIn,int endIn) {
if(startPre>endPre||startIn>endIn)
return NULL;
TreeNode* root=new TreeNode(pre[startPre]);
for(int i=startIn;i<=endIn;i++)
if(vin[i]==pre[startPre]){
root->left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,vin,startIn,i-1);
//更新左子树的前序[startPre+1,startPre+i-startIn],l_len=i-startIn;中序[startIn,i-1];
root->right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,vin,i+1,endIn);
//更新右子树的前序[startPre+i-startIn+1,endPre];中序[i+1,endIn];
//更新前序的首末要找准
break;
}
return root;
}
11
vector<vector<int> > Print(TreeNode* pRoot) {
// 存储结果
vector<vector<int> > results;
vector<int> rlt_temp;
// 边界条件
if(pRoot == nullptr)
return results;
// 辅助容器
stack<TreeNode*> stk[2]; // stk[0]是奇数层,stk[1]是偶数层
int now = 0;
int next = 1;
TreeNode* temp=pRoot;
// 根节点入栈
stk[now].push(temp);
// 遍历两个栈,当两个栈均为空时,跳出循环
while(!stk[now].empty() || !stk[next].empty()){
// 存储遍历结果
temp = stk[now].top();
rlt_temp.push_back(temp->val);
stk[now].pop();
// 当前层是奇数或偶数
if(now==0)
{
// 当前层是奇数时,左子树先入栈,右子树后入栈
if(temp->left!=nullptr)
stk[next].push(temp->left);
if(temp->right!=nullptr)
stk[next].push(temp->right);
}
else
{
// 当前层是偶数时,右子树先入栈,左子树后入栈
if(temp->right!=nullptr)
stk[next].push(temp->right);
if(temp->left!=nullptr)
stk[next].push(temp->left);
}
// 当前层为空时,打印下一层
if(stk[now].empty())
{
results.push_back(rlt_temp);
rlt_temp.clear();
now=1-now;
next = 1-next;
}
}
return results;
}