您的位置:首页 > 其它

二叉树题目

2017-09-16 21:52 260 查看

二叉树常见题目

结点结构

struct TreeNode{
int val;
TreeNode(int x):val(x){}
TreeNode*left;
TreeNode*right;
}


1.计算节点个数

递归解法:

如果二叉树为空,节点个数为0

如果二叉树不为空,那么节点个数 = 左子树结点个数 + 右子树结点个数 + 1

int GetNodeNum(TreeNode*root){
if(root==nullptr)
return 0;
return GetNodeNum(root->left)+GetNodeNum(root->right)+1;
}


2.求二叉树深度

如果二叉树为空,二叉树的深度为0

如果二叉树不为空,二叉树的深度 = max (左子树深度,右子树深度) + 1

int GetDepth(TreeNode*root){
if(root==nullptr)
return 0;
int depleft  = GetDepth(root->left);
int depright = GetDepth(root->right);
return max(depleft ,depright ) + 1;
}


3.将二叉查找树转换成双向链表

TreeNode*Convert(TreeNode*root){
if(root==nullptr)
return nullptr;
if(root->left==nullptr&&root->right==nullptr)
return root;
TreeNode *left = Convert(root->left);//这里是为了找到左子树最左边的叶子结点
TreeNode* cur = left;
while(cur!=nullptr&&cur->right!=nullptr){
cur = cur->right;
}
if(left!=nullptr){//在刚开始的时候这个curr==left
curr->next = root;
root->left = curr;
}
Treenode*right = Convert(root->right);
if(right!=nullptr)
{
right->left = root;
root->right = right;
}
return left!=nullptr ?left :root;
//返回的总是最左边的位置,如果左边为空返回根结点,否则返回左边结点
}


4.求二叉树第k层节点个数

递归解法:

如果二叉树为空或者k<1返回0;

如果二叉树不为空并且k==1,返回1

如果二叉树不为空并且k>1,返回左子树中k-1层的节点个数+右子树k-1层节点个数之和

int GetNodeNumKthLevel(TreeNode*root,int k){
if(root==nullptr||k<1)
return 0;
if(k==1)
return 0;
int numleft = GetNodeNumKthLevel(root->left,k-1);
int numright = GetNodeNumKthLevel(root->right,k-1);
return (numleft +numright );
//返回的是左边结点个数+右边结点个数
}


5.求二叉树中叶子结点个数

1.如果二叉树为空,返回0

2.如果二叉树不为空,左右子树为空返回1

3.如果二叉树不为空,左右子树不为空,返回左边结点个数+右边结点个数

int GetLeafNodeNum(TreeNode*root){
if(root==nullptr)
return 0;
if(root->left==nullptr&&root->right==nullptr)
return 1;
int numleft= GetLeafNodeNum(root->left);
int numright= GetLeafNodeNum(root->right);
return (numleft+numright);
}


6.判断两棵二叉树是否结构相同

首先搞清楚,结构相同;并不代表结点内的数据相同

/*空 空

空 不空

不空 空

不空 不空 :继续判断*/

1. 如果两根二叉树都为空,返回真

2. 如果两棵二叉树,一个空,另一个不空,返回假

3. 如果两棵二叉树都不为空,如果对应的左子树和右子树结构相同,返回真,其它返回假

bool Structcmp(TreeNode*root1,TreeNode*root2){
if(root1==nullptr&&root2==nullptr)
return true;
else if(root1==nullptr || root2==nullptr)
return false;
bool resultleft = Structcmp(root1->left,root2->left);
bool resultright = Structcmp(root1->right,root2->right);
return (resultleft &&resultright );
}


7.判断二叉树是不是平衡二叉树

int treedepth(TreeNode*root)
{
if (root == nullptr)
return 0;
int left = treedepth(root->left);
int right = treedepth(root->right);
return (left > right) ? (left + 1) : (right + 1);
//return max(left,right) + 1;
}
bool Isbalanced_tree(TreeNode*root){
if (root == nullptr)
return true;//如果二叉树结点为空返回真
int left = treedepth(root->left);
int right = treedepth(root->right);
if (abs(left - right) > 1)
return false;//如果高度差大于1为假
//此处返回的是递归判断,左右子树是否为平衡二叉树
return Isbalanced_tree(root->left) && Isbalanced_tree(root->right);
}


8.求二叉树的镜像

TreeNode*mirror(TreeNode*root)
{
if (!root)
return nullptr;
TreeNode*p_left = mirror(root->left);
//只要不停的调用就会出现栈
TreeNode*p_right = mirror(root->right);
root->left = p_right;
root->right = p_left;
return root;//如果子为空,返回空。否则返回根节点
}
/*
一左一右交换左右子树,然后交换其指向,深度递归
*/


9.求二叉树的最小深度

int mini_depth(TreeNode*root)
{
if (!root)
return 0;//直接判断左右子结点,是否存在然后根据此进行返回
if (!root->left)//求出左子树的高度
return mini_depth(root->left) + 1;//左边子树高度
if (!root->right)//求出右子树的高度
return mini_depth(root->right) +1;//右子树高度
return min(mini_depth(root->left), mini_depth(root->right)) + 1;
//返回左右子树中较小的那个高度
}


10.判断二叉树是不是完全二叉树

如果二叉树的深度为h,除第h层外,其它(1~h-1)的结点数都达到最大个数,第h层所有的结点都连续集中在最左边,这就是完全二叉树。

按层遍历二叉树,当遇到第一个结点的左子树为空时,则该结点左右子树必须为空,而且此结点后的结点左右子树必须为空,否则不是完全二叉树

bool isCompleteBinary_tree(TreeNode*root)
{
if (root == nullptr)
return false;
queue<TreeNode*> q;
q.push(root);
bool hasnochild = false;
bool result = true;
while (!q.empty()){
TreeNode* pnode = q.front();
q.pop();
if (hasnochild){
if (pnode->left != nullptr || pnode->right != nullptr){
result = false;
break;
}
}
else
{
if (pnode->left != nullptr&&pnode->right != nullptr){
q.push(pnode->left);
q.push(pnode->right);
}
else if (pnode->left != nullptr&&pnode->right == nullptr){
hasnochild = true;
q.push(pnode->left);
}
else if (pnode->left == nullptr&&pnode->right != nullptr){
result = false;
break;
}
else
{//此处指当左右都为空的时候
hasnochild = true;
}
}
}
return result;
}


11.求二叉树中两个结点的最低公共祖先结点

求最低公共结点,采用深度递归从头结点到包含此结点的路径,然后遍历到开始变化的那个结点的位置就是最低公共祖先

注意:

1. 如果两个结点分别在根节点的左右子树中,则返回根节点

2. 如果两个结点都在左子树,则递归处理左子树;如果两个结点都在右子树,则递归处理右子树

bool GetNodePath(TreeNode*root, TreeNode*pNode, vector<TreeNode*>&path){
if (root == pNode) //路径作为传入传出参数
{
path.push_back(root);
return true;
}
if (root == nullptr)
return false;
/*这里是先进行的判断,然后在存入容器的操作,如果先直接压入容器那么就应该有回退的操作
递归结束条件,当一直没找到,为空的时候直接返回,当找到了压入容器,改变标记位置,返回*/
path.push_back(root);
bool found = false;
found = GetNodePath(root->left, pNode, path);
//采用先序遍历,先把根节点存储然后往下判断
if (!found)//如果左边没找到,递归查找右子树
found = GetNodePath(root->right, pNode, path);
if (!found)
path.pop_back();
//这里是右子树操作,如果没找到要回退,然后进行操作
return found;
}
TreeNode* Find_commonnode(TreeNode*root, TreeNode*pNode1, TreeNode*pNode2){
if (root == nullptr || pNode1 == nullptr || pNode2 == nullptr)
return nullptr;
vector<TreeNode*>path1;
bool result1 = GetNodePath(root, pNode1, path1);
vector<TreeNode*>path2;
bool result2 = GetNodePath(root, pNode2, path2);
if (!result1 || !result2)
return nullptr;
TreeNode*plast = nullptr;
vector<TreeNode*>::const_iterator iter1 = path1.begin();
vector<TreeNode*>::const_iterator iter2 = path2.begin();
while (iter1 != path1.end() && iter2 != path2.end())
{
if (*iter1 == *iter2)
plast = *iter1;//将结点的内容存储起来
else
break;
iter1++;
iter2++;
}
return plast;
}


12.求二叉树中距离最远的结点之间的距离

递归解法:

1.如果二叉树为空返回0,一种方式是包含此结点,计算左右子树的最大深度

2.不包含此结点,计算左有子树中最大的距离,然后从三者之间计算求出最大值

int GetMaxDistance(TreeNode*root)
{
if (root == nullptr)
return 0;
int res = depth(root->left)+depth(root->right);
return max(res, max(GetMaxDistance(root->left), GetMaxDistance(root->right)));
}
int depth(TreeNode*root){
if (root == nullptr)
return 0;
return max(depth(root->left),depth(root->right)) + 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树