二叉树面试题以及线索化二叉树

来源:互联网 发布:飞信邮件群发软件 编辑:程序博客网 时间:2024/06/05 12:06

二叉树面试题

完整代码:

#include <iostream>using namespace std;#include <queue>#include <stack>template<class T>//孩子表示法struct son{    son(const T& data)    : _left(NULL)    , _right(NULL)    , _data(data)    {}    son<T> *_left;    son<T> *_right;    T _data;};template<class T>//二叉树模版类class BinaryTree{    typedef son<T> son;public:    //无参构造二叉树    BinaryTree()        :_head(NULL)    {}    ////构造二叉树1    //BinaryTree(const T*array, size_t size, const T& invalid)    //{    //  size_t index = 0;    //  _head = CreatTree(array, size, invalid, index);    //}    //构造二叉树2    BinaryTree(const T* array, size_t size)    {        size_t index = 0;        CreateBinaryTree(_head, array, size, index);    }    //销毁二叉树    ~BinaryTree()    {        ReleaseBinaryTree(_head);    }    //拷贝构造    BinaryTree(const BinaryTree<T> &cp)    {        _head = CopyBinaryTree(cp._head);    }    //赋值    BinaryTree& operator=(const BinaryTree<T> &s)    {        if (this != &s)        {            BinaryTree<T> tmp(s);            swap(_head,tmp._head);        }        return *this;    }    //先序遍历    void Preorder()    {        cout << "先序遍历: ";        PreorderTraversal(_head);        cout << endl;    }    //非递归先序遍历    void PreorderNonRecursive()    {        cout << "非递归先序遍历: ";        PreorderTraversalNonRecursive(_head);        cout << endl;    }    //中序遍历    void Inorder()    {        cout << "中序遍历: ";        InorderTraversal(_head);        cout << endl;    }    //非递归中序遍历    void InorderNonRecursive()    {        cout << "非递归中序遍历: ";            InorderTraversalNonRecursive(_head);        cout << endl;    }    //后序遍历    void Postorder()    {        cout << "后序遍历: ";        PostorderTraversal(_head);        cout << endl;    }    //非递归后序遍历    void PostorderNonRecursive()    {        cout << "非递归后序遍历: ";        PostorderTraversalNonRecursive(_head);        cout << endl;    }    //树的深度    size_t height()    {        return HeightBinaryTree(_head);    }    //叶子结点个数    size_t Leaf()    {        cout << "叶子结点个数: ";        return LeafNode(_head);    }    //广度遍历(层序遍历)    void BreadFirst()    {        cout << "广度遍历: ";        BreadthFirst(_head);        cout << endl;    }    //某一层的结点个数    size_t LayerNode(size_t k)    {        if (height() < k)            return 0;        cout << "第K层的结点个数: ";        return LayerNodes(_head, k);    }    //查找值为data的结点    son* Find(const T&data)    {        return FindNode(_head, data);    }    //查找某个结点的双亲结点    void FindParents(const T&data)    {        son* tmp = Find(data);        son* node = FindNodeParents(_head, tmp);        if (node)        {            cout << "该结点的双亲结点存在,地址为: " << node <<"数据是:"<< node->_data << endl;        }        else        {            cout << "该结点的双亲结点不存在" << endl;        }    }    //结点总数    size_t NodeCount()    {        cout << "结点总数为:";        return GetcountNode(_head);    }    //二叉树镜像    void Image()    {        cout << "二叉树镜像,前序输出:";        BinaryTreeImage(_head);        PreorderTraversal(_head);        cout << endl;    }    //求一棵树是否是完全二叉树    bool Complete()    {        return CompleteBinaryTree(_head);    }    //根据中序和前序重建二叉树    void InPrerebuild(T *preOrder, int startPre, int endPre, T *inOrder, int startIn, int endIn)    {        _head = rebuild(preOrder, startPre, endPre, inOrder, startIn, endIn);        cout << "重建二叉树,前序输出:";        PreorderTraversal(_head);        cout << endl;    }private:    //构造二叉树2    void CreateBinaryTree(son*& head, const T* array, size_t size, size_t& index)    {        if (array[index] != '#' && index < size)        {            head = new son(array[index]);            CreateBinaryTree(head->_left, array,size,++index);            CreateBinaryTree(head->_right,array,size,++index);        }    }    //构造二叉树1    //son* CreatTree(const T* a, size_t size, const T& invalid, size_t& index)//注意index的传值方式      //{    //  son* head = NULL;    //  if (a[index] != invalid && index < size)//按先序遍历建树      //  {    //      head = new son(a[index]);    //      head->_left = CreatTree(a, size, invalid, ++index);    //      head->_right = CreatTree(a, size, invalid, ++index);    //  }    //  return head;    //}    //释放二叉树    void ReleaseBinaryTree(son *head)    {        if (head)        {            ReleaseBinaryTree(head->_left);            ReleaseBinaryTree(head->_right);            delete head;            head = NULL;        }    }    //拷贝二叉树    son *CopyBinaryTree(son *head)    {        son *Newhead = NULL;        if (head)        {            Newhead = new son(head->_data);            if (head->_left)                Newhead->_left = CopyBinaryTree(head->_left);            if (head->_right)                Newhead->_right = CopyBinaryTree(head->_right);        }        return Newhead;    }    //先序遍历二叉树    void PreorderTraversal(son *head)    {        if (head)        {            cout <<head->_data <<" ";            PreorderTraversal(head->_left);            PreorderTraversal(head->_right);        }    }    //非递归先序遍历    void PreorderTraversalNonRecursive(son *head)    {        stack<son *> Stack;        if (head == NULL)        {            return;        }        Stack.push(head);        while(!Stack.empty())        {            son *cur = Stack.top();            cout << cur->_data <<" ";            Stack.pop();            if (cur->_right)                Stack.push(cur->_right);            if (cur->_left)                Stack.push(cur->_left);        }    }    //中序遍历    void InorderTraversal(son *head)    {        if (head)        {            InorderTraversal(head->_left);            cout << head->_data << " ";            InorderTraversal(head->_right);        }    }    //非递归中序遍历    void InorderTraversalNonRecursive(son *head)    {        stack<son *> Stack;        if (!head)        {            return;        }        while (head || !Stack.empty())//只要满足一个就执行        {            while (head)            {                Stack.push(head);                head = head->_left;            }            head = Stack.top();             cout << head->_data <<" ";            Stack.pop();            head = head->_right;        }    }    //后序遍历    void PostorderTraversal(son *head)    {        if (head)        {            PostorderTraversal(head->_left);            PostorderTraversal(head->_right);            cout << head->_data <<" ";        }    }    //非递归后序遍历    void PostorderTraversalNonRecursive(son *head)    {        son* cur = head;        son* prev = NULL;//上一个访问过的数据          stack<son*> s;        while (!s.empty() || cur)//只要当前节点和栈不同时为空,就说明树没遍历完          {            //后序遍历,遇到树根节点直接将其压栈              while (cur)            {                s.push(cur);                cur = cur->_left;            }            son* top = s.top();//取栈顶元素,但不一定能访问              //当节点右子树为空或已经访问过时对其直接进行访问              if (top->_right == NULL || top->_right == prev)            {                cout << top->_data << " ";                prev = top;//将prev更新为已经访问的节点                  s.pop();            }            else//以子问题的方式去访问右子树              {                cur = top->_right;            }        }    }    //树的深度    size_t HeightBinaryTree(son *head)    {        if (head == NULL)            return 0;        if (head->_left == NULL && head->_right == NULL)            return 1;        size_t LeftHeight = HeightBinaryTree(head->_left);        size_t rightHeight = HeightBinaryTree(head->_right);        return LeftHeight > rightHeight ? LeftHeight + 1 : rightHeight + 1;    }    //叶子节点个数    size_t LeafNode(son *head)    {        if (head == NULL)            return 0;        if (head->_left == NULL && head->_right == NULL)            return 1;        return (LeafNode(head->_left) + LeafNode(head->_right));    }    //广度遍历    void BreadthFirst(son *head)    {        queue<son*> s;        if (head)        {            s.push(head);        }        while (!s.empty())        {            son *tmp = s.front();            s.pop();            cout << tmp->_data << " ";            if (tmp->_left)                s.push(tmp->_left);            if (tmp->_right)                s.push(tmp->_right);        }    }    //第K层的结点个数    size_t LayerNodes(son *head,size_t k)    {        if (head == NULL)            return 0;        if (k == 1)            return 1;        return LayerNodes(head->_left, k - 1) + LayerNodes(head->_right, k - 1);    }    //查找值为data的结点是否存在    son *FindNode(son *head,const T&data)    {        if (head == NULL)            return NULL;        if (head->_data == data)            return head;        son* ret = NULL;        if (ret = FindNode(head->_left, data))            return ret;        return FindNode(head->_right, data);    }    //查找某个结点的双亲结点    son *FindNodeParents(son *head, son *node)    {        if (head == NULL || node == NULL || head == node)        {            return NULL;        }        if (head->_left == node || head->_right == node)            return head;        son* Parents = NULL;        if (Parents = FindNodeParents(head->_left, node))            return Parents;        return FindNodeParents(head->_right, node);    }    //结点总数    size_t GetcountNode(son *head)    {        size_t count = 0;        if (NULL == head)        {            count = 0;        }        else        {            //当前节点 = 左子树节点 + 右子树节点 + 1              count = GetcountNode(head->_left) + GetcountNode(head->_right) + 1;        }        return count;    }    //求一个结点是否在二叉树中    bool IsNodeExist(son *head, son *node)    {        if (node == head)            return ture;        if ((son*tmp = FindNodeParents(head, node)))        {            return true;        }        return false;    }    //二叉树镜像    void BinaryTreeImage(son *head)    {        if (head)        {            swap(head->_left, head->_right);            BinaryTreeImage(head->_left);            BinaryTreeImage(head->_right);        }    }    //求一棵树是否是完全二叉树    bool CompleteBinaryTree(son *head)    {        if (head == NULL)            return true;        queue<son *> s;        s.push(head);        bool flag = false;        while (!s.empty())        {            son *cur = s.front();            if (flag)            {                if (cur->_left || cur->_right)                    return false;            }            else            {                if (cur->_left &&cur->_right)                {                    s.push(cur->_left);                    s.push(cur->_right);                    flag = true;                }                else if (cur->_left)                {                    s.push(cur->_left);                    flag = true;                }                else if (cur->_right)                {                    return false;                }                else                    flag = true;            }            s.pop();        }        return true;    }    //根据中序和前序重建二叉树    son *rebuild(T *preOrder, int startPre, int endPre, T *inOrder, int startIn, int endIn)    {        //先序遍历和中序遍历长度应相等           if (endPre - startPre != endIn - startIn)             return NULL;        //起始位置不应大于末尾位置           if (startPre > endPre)             return NULL;        //先序遍历的第一个元素为根节点           son *head = new son(preOrder[startPre]);        head->_left = NULL;        head->_right = NULL;        //先序遍历和中序遍历只有一个元素时,返回该节点           if (startPre == endPre)             return head;        //在中序遍历中找到根节点           int index = 0;        int length = 0;        for (index = startIn; index <= endIn; index++)        {            if (inOrder[index] == preOrder[startPre])                 break;        }        //若未找到,返回空           if (index > endIn)             return NULL;        //有左子树,递归调用构建左子树           if (index > startIn)        {            length = index - startIn;            head->_left = rebuild(preOrder, startPre + 1, startPre + 1 + length - 1, inOrder, startIn, startIn + length - 1);        }        //有右子树,递归调用构建右子树           if (index < endIn)        {            length = endIn - index;            head->_right = rebuild(preOrder, endPre - length + 1, endPre, inOrder, endIn - length + 1, endIn);        }        return head;    }private:    son *_head;};void Test(){    //int arr[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' };    //size_t size = sizeof(arr) / sizeof(arr[0]);    //BinaryTree<int> bt(arr, size,'#');    //BinaryTree<int> bt(arr, size);    char str[] = "ABC##D##E#F##";    size_t size = strlen(str);    BinaryTree<char> bt(str, size);    BinaryTree<char> bt1(bt);    BinaryTree<char> bt2;    bt2 = bt1;    bt.Preorder();    bt.PreorderNonRecursive();    bt1.Inorder();    bt1.InorderNonRecursive();    bt2.Postorder();    bt2.PostorderNonRecursive();    bt2.BreadFirst();    cout << "树的深度: "<< bt2.height() << endl;    cout << bt2.Leaf()<< endl;    cout << bt2.LayerNode(3) << endl;    cout <<bt2.Find('B')<<endl;    bt2.FindParents('B');    cout << bt2.NodeCount() << endl;    bt2.Image();    bt2.Image();    cout << bt2.Complete()<< endl;    char str1[] = "ABCDEF";    char str2[] = "CBDAEF";    bt2.InPrerebuild(str1,0,6,str2,0,6);}int main(){    Test();    system("pause");    return 0;}

测试结果:

这里写图片描述

线索化二叉树以及遍历

完整代码:

#include <iostream>using namespace std;enum Point{ LINK, THREAD };template <class T>struct son{    son(const T &data)    :_data(data)    ,_left(NULL)    ,_right(NULL)    , _parent(NULL)    ,_leftThread(LINK)    ,_rightThread(LINK)    {}    T _data;    son<T> *_left;    son<T> *_right;    son<T> *_parent;    Point _leftThread;    Point _rightThread;};template <class T>class BinaryTreeThd{    typedef son<T> son;public:    BinaryTreeThd()        :_head(NULL)    {}    //构造    BinaryTreeThd(const T* array, size_t size)    {        size_t index = 0;        son *parent = NULL;        CreateBinaryTree(_head, array, size, index, parent);    }    //前序线索化    void Prethd()    {        son *prev = NULL;        PreTreethd(_head, prev);    }    //遍历前序线索化    void Preorderthd()    {        cout << "遍历前序线索化: ";        Preorder();        cout << endl;    }    //中序线索化    void Inthd()    {        son *prev = NULL;        InTreethd(_head, prev);    }    //遍历前序线索化    void Inorderthd()    {        cout << "遍历先序线索化: ";        Inorder();        cout << endl;    }    //后序线索化    void Postthd()    {        son *prev = NULL;        PostTreethd(_head, prev);    }    //遍历后序线索化    void Postorderthd()    {        cout << "遍历后序线索化: ";        Postorder();        cout << endl;    }private:    //构造二叉树    void CreateBinaryTree(son*& head, const T* array, size_t size, size_t& index, son *&parent)    {        if (array[index] != '#' && index < size)        {            head = new son(array[index]);            head->_parent = parent;            CreateBinaryTree(head->_left, array, size, ++index, head);            CreateBinaryTree(head->_right, array, size, ++index, head);        }    }    //前序线索化    void PreTreethd(son *head,son *&prev)    {        if (head)        {            //线索化左指针域            if (NULL == head->_left)            {                head->_left = prev;                head->_leftThread = THREAD;            }            //线索化前一个结点的右指针域            if (prev && NULL == prev->_right)            {                prev->_right = head;                prev->_rightThread = THREAD;            }            prev = head;            if (LINK == head->_leftThread)                PreTreethd(head->_left, prev);            if (LINK == head->_rightThread)                PreTreethd(head->_right, prev);        }    }    //中序线索化    void InTreethd(son *head, son *&prev)    {        if (head)        {            InTreethd(head->_left, prev);            //线索化左指针域            if (NULL == head->_left)            {                head->_left = prev;                head->_leftThread = THREAD;            }            //线索化前一个结点的右指针域            if (prev && NULL == prev->_right)            {                prev->_right = head;                prev->_rightThread = THREAD;            }            prev = head;            if (LINK == head->_rightThread)                InTreethd(head->_right, prev);        }    }    //后序线索化    void PostTreethd(son *head, son *&prev)    {        if (head)        {            PostTreethd(head->_left, prev);            PostTreethd(head->_right, prev);            //线索化左指针域            if (NULL == head->_left)            {                head->_left = prev;                head->_leftThread = THREAD;            }            //线索化前一个结点的右指针域            if (prev && NULL == prev->_right)            {                prev->_right = head;                prev->_rightThread = THREAD;            }            prev = head;        }    }    //遍历前序线索化    void Preorder()    {        son *cur = _head;        while (cur)        {            while (LINK == cur->_leftThread)            {                cout << cur->_data << " ";                cur = cur->_left;            }            cout << cur->_data<< " ";            cur = cur->_right;            ////访问连在一起的后继            //while (THREAD == cur->_rightThread)            //{            //  cur = cur->_right;            //  cout << cur->_data << " ";            //}            //if (LINK == cur->_leftThread)            //  cur = cur->_left;            //else            //  cur = cur->_right;        }    }    //遍历中序线索化    void Inorder()    {        son *cur = _head;        son* prev = NULL;        while (cur)        {            while (LINK == cur->_leftThread)            {                cur = cur->_left;            }            cout << cur->_data << " ";            prev = cur;            while (THREAD == cur->_rightThread)            {                cur = cur->_right;                cout << cur->_data << " ";                prev = cur;            }            cur = cur->_right;        }    }    //遍历后序线索化    void Postorder()    {        son* cur = _head;        son* prev = NULL;        while (cur)        {            //寻找最左节点              while (cur->_left != prev && cur->_leftThread == LINK)            {                cur = cur->_left;            }//cur==_node或NULL结束循环              //访问后继              while (cur && cur->_rightThread == THREAD)//当前节点的右指针为线索              {                cout << cur->_data << " ";                prev = cur;                cur = cur->_right;            }            if (cur == _head)//判断节点是否指向了根节点              {                cout << cur->_data << endl;                return;            }            while (cur && cur->_right == prev)            {                cout << cur->_data << " ";                prev = cur;                cur = cur->_parent;//向上一层走              }            if (cur && cur->_rightThread == LINK)//cur->_rightThread == LINK(当前节点的右指针为子树)              {                cur = cur->_right;            }        }    }private:    son *_head;};void test(){    char str[] = "ABC##D##E#F##";    size_t size = strlen(str);    BinaryTreeThd<char> bt(str, size);    bt.Prethd();    bt.Preorderthd();    size_t size1 = strlen(str);    BinaryTreeThd<char> bt1(str,size1);    bt1.Inthd();    bt1.Inorderthd();    size_t size2 = strlen(str);    BinaryTreeThd<char> bt2(str,size2);    bt2.Postthd();    bt2.Postorderthd();}int main(){    test();    system("pause");    return 0;}

测试结果:
这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果8手机弯了怎么办 苹果8p手机弯了怎么办? 美版iphone弯了怎么办 oppor9手机听筒声音小怎么办 苹果7摔弯了屏幕怎么办 苹果手机压弯了怎么办 京东买的电脑坏了怎么办 拼多多低价乱价怎么办 厂家不通过经销商直接发货怎么办 媳妇吵架说我全家有病怎么办 全家都不尊重媳妇怎么办 招商闪电贷有额度不通过怎么办 闪电贷页面登录不进去怎么办 91借钱极速逾期怎么办 论文没过拿不到毕业证怎么办 大学论文不过拿不到毕业证怎么办 转店被黑中介骗了钱怎么办? 被星外转铺骗了怎么办 店铺转了后悔了怎么办 商铺转让不出去怎么办? 和包券密码丢失怎么办 天猫购物卷兑换不了怎么办 淘宝新店每天只有几个访客怎么办 注册淘宝企业店铺需要审核怎么办 淘宝店铺被投诉知识产权怎么办 一般违规扣48分怎么办 金税盘处于报税期不能开票怎么办 小规模税率开错了怎么办 我是代购卖家被买家投诉偷税怎么办 天猫盒子内存不够怎么办 天猫品牌申请不通过怎么办 天猫商家发货发个空包裹怎么办 无限流量怎么办没有4g 海外直邮身份证过期了怎么办 买车的人不过户怎么办 天猫精灵球泡离线怎么办 花呗被骗了2万怎么办 天猫公司变更地址发票怎么办 支付宝自助解限怎么办 支付宝16岁限额怎么办 支付宝提不了现怎么办