二叉树面试题

1. 前序/中序/后序遍历(非递归)
前序

void PrevOrderNonR()
    {
        stack<Node*> s;
        Node* cur = _root;

        while (cur || !s.empty())
        {
            while (cur)
            {
                cout<<cur->_data<<" ";
                s.push(cur);
                cur = cur->_left;
            }

            // top从栈取出来表示这个节点的左子树访问过了
            // 剩余右子树还没访问,循环子问题访问右树
            Node* top = s.top();
            s.pop();

            // 子问题的方式访问右树
            cur = top->_right;
        }

        cout<<endl;
    }

中序

void InOrder()
    {
        _InOrder(_root);
        cout<<endl;
    }

    void InOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }

            Node* top = s.top();
            s.pop();

            cout<<top->_data<<" ";

            // 子问题
            cur = top->_right;
        }
    }

后序

 void PostOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        Node* prev = NULL;

        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }

            Node* front = s.top();
            if (front->_right == NULL || front->_right == prev)
            {
                cout<<front->_data<<" ";
                prev = front;
                s.pop();
            }
            else
            {
                // 子问题
                cur = front->_right;
            }
        }
        cout<<endl;
    }

判断一棵二叉树是否是平衡二叉树

//判断一棵树是不是平衡二叉树
bool IsBalancedTree_old(Node* root)
{
    if (root == NULL)
        return true;
    int lenleft = BinaryTreeDepth(root->Lchild);//每往下一层,计算一次深度,时间复杂度N^2
    int lenright = BinaryTreeDepth(root->Rchild);
    int temp = lenleft - lenright;
    if (temp >1 || temp < -1)
        return false;
    return IsBalancedTree_old(root->Lchild) && IsBalancedTree_old(root->Rchild);//满足条件,计算它的下一层的左右子树
}




//判断是否为平衡二叉树(优化)
bool _IsBlancedtree_new(Node* root,int* pDepth)
{
    if (root == NULL)
    {
        *pDepth = 0;
        return true;
    }
    int left, right;
    if (_IsBlancedtree_new(root->Lchild, &left) && _IsBlancedtree_new(root->Rchild, &right))//后序遍历思想
    {
        int temp = left - right;
        if (temp <= 1 && temp >= -1)//拿到深度值
        {
            *pDepth = left > right ? left + 1 : right + 1;
            return true;
        }
    }

    return false;
}
bool IsBlancedTree_new(Node* root)
{
    int pDepth;
    bool tag = _IsBlancedtree_new(root, &pDepth);
    return tag;
}

求二叉树的镜像

//求一颗二叉树的镜像 :两棵树左右对称
void  Mirror(Node* root)
{
    if (root == NULL)
        return ;
    if (root->Lchild == NULL && root->Rchild == NULL)
        return ;
    Node* temp = root->Lchild;//交换左右子树
    root->Lchild = root->Rchild;
    root->Rchild = temp;
    if (root->Lchild)//递归下去
        MirrorRecursively(root->Lchild);
    if (root->Rchild)
        MirrorRecursively(root->Rchild);
}

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

bool GetNodePath(Node* root, Node* x, stack<Node*>& paths)
    {
        if (root == NULL)
            return false;

        paths.push(root);
        if (root == x)
            return true;

        if(GetNodePath(root->_left, x, paths))
            return true;

        if (GetNodePath(root->_right, x, paths))
            return true;

        paths.pop();
        return false;
    }

Node* GetCommonAncestor(Node* root, Node* x1, Node* x2)
    {
        assert(x1 && x2);
        stack<Node*> paths1;
        stack<Node*> paths2;
        if (GetNodePath(root, x1, paths1) == false)
            return NULL;
        if (GetNodePath(root, x2, paths2) == false)
            return NULL;

        while(paths1.size() != paths2.size())
        {
            if (paths1.size() > paths2.size())
                paths1.pop();
            else
                paths2.pop();
        }

        while (1)
        {
            if (paths1.top() == paths2.top())
            {
                return paths1.top();
            }

            paths1.pop();
            paths2.pop();
        }

    }
Node * FindLCA(Node * node, Node * target1, Node * target2)
{
    if (node == nullptr)
        return nullptr;
    if (node == target1 || node == target2)
        return node;

    Node * left = FindLCA(node->left, target1, target2);
    Node * right = FindLCA(node->right, target1, target2);
    if (left && right)  // 分别在左右子树
        return node;

    return left ? left : right;  // 都在左子树或右子树
}

求二叉树中最远的两个节点的距离

int _FindMaxLen(Node* root, int& maxLen)
    {
        if (root == NULL)
            return 0;

        int l = _FindMaxLen(root->_left, maxLen);
        int r = _FindMaxLen(root->_right, maxLen);
        if (l+r > maxLen)
        {
            maxLen = l+r;
        }

        return l > r ? l+1 : r+1;
    }

    int FindMaxLen(Node* root)
    {
        int max = 0;
        _FindMaxLen(root, max);
        return max;
    }

    //void _FindMaxLen(Node* root, int& maxLen)
    //{
    //  if (root == NULL)
    //      return;
    //  
    //  int l = Height(root->_left);
    //  int r = Height(root->_right);
    //  if (l + r > manLen)
    //      manLen = l + r;

    //  FindMaxLen(root->_left);
    //  FindMaxLen(root->_right);
    //}

由前序遍历和中序遍历重建二叉树(如:前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)

Node* ReBulidTree(char*& prev, char* inStart, char* inEnd)
    {
        if (*prev=='\0')
            return NULL;

        Node* root = new Node(*prev);
        if (inStart == inEnd)
            return root;

        char* pos = inStart;
        while (pos <= inEnd)
        {
            if (*pos == *prev)
                break;
            ++pos;
        }
        assert(pos <= inEnd);

        // [inStart,pos-1]
        // [pos+1,inEnd]
        root->_left = ReBulidTree(++prev, inStart, pos-1);
        root->_right = ReBulidTree(++prev, pos+1, inEnd);

        return root;
    }

判断一棵树是否是完全二叉树

bool IsCompleteTree(Node* root)
    {
        if (root == NULL)
            return true;

        bool tag = true;
        queue<Node*> q;
        q.push(root);
        while (!q.empty())
        {
            Node* front = q.front();
            q.pop();
            if (front->_left)
            {
                if (tag == false)
                    return false;

                q.push(front->_left);
            }
            else
            {
                tag = false;
            }

            if (front->_right)
            {
                if (tag == false)
                    return false;

                q.push(front->_right);
            }
            else
            {
                tag = false;
            }
        }

        return true;
    }

将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

Node* ToSortList(Node* root)
    {
        Node* prev = NULL;
        ToSortList(root, prev);

        while (root && root->_left)
        {
            root = root->_left;
        }

        return root;
    }

    Node* _ToSortList(Node* cur, Node*& prev)
    {
        if (cur == NULL)
            return;

        _ToSortList(cur->_left, prev);

        cur->_left = prev;
        if (prev)
            prev->_right = cur;

        prev = cur;

        _ToSortList(cur->_right, prev);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值