二叉树题目

来源:互联网 发布:网络会员管理系统免费 编辑:程序博客网 时间:2024/06/01 08:47

二叉树常见题目

结点结构

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

1.计算节点个数

递归解法:

  1. 如果二叉树为空,节点个数为0
  2. 如果二叉树不为空,那么节点个数 = 左子树结点个数 + 右子树结点个数 + 1
int GetNodeNum(TreeNode*root){    if(root==nullptr)        return 0;    return GetNodeNum(root->left)+GetNodeNum(root->right)+1;}

2.求二叉树深度

  1. 如果二叉树为空,二叉树的深度为0
  2. 如果二叉树不为空,二叉树的深度 = 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层节点个数

递归解法:

  1. 如果二叉树为空或者k<1返回0;
  2. 如果二叉树不为空并且k==1,返回1
  3. 如果二叉树不为空并且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;    }
原创粉丝点击