面试相关之树

来源:互联网 发布:php urlencode加号 编辑:程序博客网 时间:2024/05/21 15:01

1.树的子结构:输入两棵树A和B,判断B是不是A的子结构
思路:第一步在A中跟B的根节点相同的节点R
第二步: 以R为根的子树是否包含和B一样的结构

给定一棵树,求整棵树上节点间的最大距离

2..完成一个函数,输入一个二叉树,输出它的镜像
解法:先前序遍历树的每一个节点,当该节点存在子节点的时候,交换子节点的值。

void Mirror(Node *root){    if((root == NULL) || (root->next == NULL &&root->right))        return ;    Node *pTemp = root->left;    root->left = root->right;    root->right = pTemp;    if(root->left)        Mirror(root->left);    if(root->right)        Mirror(root->right);}

3.逐层遍历二叉树

void printFromTop(Node* root){    if(!root)        return ;    deque<Node *>  q;    q.push_back(root);    while(q.size()){        Node *pNode = q.front();        dequeue.pop_front();        cout<<pNode.data<<endl;        if(pNode->left)            q.push_back(pNode->left);        if(pNode ->right)            q.push_back(pNode->right);    }}

4.二叉树中和为某一值的路径 :输入二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径
5.非递归方式中序遍历中序二叉树

void InOrderTree(Node *root){    stack<Node *> s;    Node *p = root;    while(p != NULL || !s.empty()){        while(p != NULL){        s.push(p);  //根节点入栈遍历左子树        p = p->left;        }        if(!s.empty()){            p = s.top();            s.pop();            cout<<p.data<<" ";            p = p-> right ;         }    }}

6.求二叉树中叶子节点的个数
思路:树中的叶子节点的个数 = 左子树中叶子节点的个数 + 右子树中叶子节点的个数。利用递归代码也是相当的简单

//获取叶子节点的个数int get_leaf_num(BinTreeNode *r){    if(r == NULL)//该节点是空节点,比如建树时候用'#'表示    {        return 0;    }    if(r->left==NULL && r->right == NULL)//该节点并不是空的,但是没有孩子节点    {        return 1;    }    //递归整个树的叶子节点个数 = 左子树叶子节点的个数 + 右子树叶子节点的个数        return get_leaf_num(r->left) +get_leaf_num(r->get_right);}

7.判断一个节点是否在一颗子树中

可以和当前根节点相等,也可以在左子树或者右子树中。

//判断一个节点t是否在以r为根的子树中bool is_in_tree(BinTreeNode *r,BinTreeNode *t){    if(r == NULL)    {        return false;    }    else if(r == t)    {        return true;    }    else    {        bool has = false;        if(r->get_left() != NULL)        {            has = is_in_tree(r->get_left(),t);        }        if(!has && r->get_right()!= NULL)        {            has = is_in_tree(r->get_right(),t);        }        return has;    }}

8.求两个节点的最近公共祖先

求两个节点的公共祖先可以用到上面的:判断一个节点是否在一颗子树中。(1)如果两个节点同时在根节点的右子树中,则最近公共祖先一定在根节点的右子树中。(2)如果两个节点同时在根节点的左子树中,则最近公共祖先一定在根节点的左子树中。(3)如果两个节点一个在根节点的右子树中,一个在根节点的左子树中,则最近公共祖先一定是根节点。当然,要注意的是:可能一个节点pNode1在以另一个节点pNode2为根的子树中,这时pNode2就是这两个节点的最近公共祖先了。显然这也是一个递归的过程啦:

//求两个节点的最近公共祖先BinTreeNode* get_nearest_common_father(BinTreeNode *r,BinTreeNode *pNode1,BinTreeNode *pNode2){    //pNode2在以pNode1为根的子树中(每次递归都要判断,放在这里不是很好。)    if(is_in_tree(pNode1,pNode2))    {        return pNode1;    }    //pNode1在以pNode2为根的子树中    if(is_in_tree(pNode2,pNode1))    {        return pNode2;    }    bool one_in_left,one_in_right,another_in_left,another_in_right;    one_in_left = is_in_tree(r->get_left(),pNode1);    another_in_right = is_in_tree(r->get_right(),pNode2);    another_in_left = is_in_tree(r->get_left(),pNode2);    one_in_right = is_in_tree(r->get_right(),pNode1);    if((one_in_left && another_in_right) || (one_in_right && another_in_left))    {        return r;    }    else if(one_in_left && another_in_left)    {        return get_nearest_common_father(r->get_left(),pNode1,pNode2);    }    else if(one_in_right && another_in_right)    {        return get_nearest_common_father(r->get_right(),pNode1,pNode2);    }    else    {        return NULL;    }}

9.实现一个函数检查二叉树是否平衡
遍历二叉树的每一个节点,检查该节点的左右子树是否平衡

10.给定一个整数数组,元素各不相同且按递增排列,编写一个算法,创建一棵高度最小的二叉查找树
思路:采用二分法,中间节点作为子树的root,左部分作为左子树,右部分作为右子树。

11.检查一棵二叉树是否是为二叉查找树
解法:1.中序遍历:查看left<= current < right
2. 最小/最大法:限定左右子树的取值范围并检查加上
12.先序遍历对二叉树进行序列化
1.假设序列化的结果为字符串str,初始时str为空字符串
2.先序遍历二叉树时如果遇到空节点,在str末尾”#!”
3.如果遇到不为空的节点,加上”x!”(该节点值为x)

反序列化

把str编程字符串类型的数组,依次生成节点

折纸问题

给定一棵树,判定是否是平衡二叉树

找出二叉排序树种两个错误的节点

给定一颗二叉树头结点head,判断这颗二叉树是否是完全二叉树

采用逐层遍历的方式,
如果某节点只有右孩子没有左孩子,则直接返回false,
如果某节点孩子不全,则后面的节点必须为叶子节点。否则返回false

一棵带有父节点指针的二叉树,根节点的父指指针指向null,给定某节点node,返回该节点的后继节点

方法一:
通过node节点的父指针找到根节点,由根节点中序遍历,在根据中序遍历找到node的后继节点。
时间复杂度:O(N)
空间复杂度:O(N)
方法二:
如果node有右子树,则其后继节点解释右子树上最左的节点
如果没有右子树,:
如果node是其父节点的左孩子,则父节点就是后继节点
若不是父节点的左孩子,node向上寻找,找到节点s,s的父节点为p,若节点s是p的左孩子,则p是node的后继节点,否则继续向上寻找

时间复杂度:O(L),L为node节点与其后继节点的距离

0 0
原创粉丝点击