zoukankan      html  css  js  c++  java
  • 树用递归体现:

    树由 n 个节点组成有限合集。

       当 n = 0 的时候是空树

       当 n > 0 的时候除根节点其他的节点可以划分为 m 个互不相交的有限集合,每个集合称为子树

    度:一个节点拥有子树的数目称为节点的度,度为零的节点叫叶节点,度不为零叫分支节点。树的度为所有度节点中度的最大值。 

    树的前驱和后继:节点的后继叫孩子,具有相同父亲的节点叫兄弟,节点的前驱叫父亲。 

    树的高度:是树中节点最大层次

    有序树:树中节点从左到右是有序的,且子树不能互换位置

    深林:由n棵互不相交的树组成的集合

    节点: 树中的节点包含了一个数据和指向其他节点的指针

     线性非线性:从根节点到叶节点是非线性的,从叶节点到根节点是线性的(等同链表)

    树的表示方法:

    双亲孩子表示法:

      a. 每个节点都有指向父亲的指针

      b. 每个节点都有指向若干个孩子的指针

    #ifndef GTREENODE_H
    #define GTREENODE_H
    
    #include"Tree.h"
    #include"LinkList.h"
    
    namespace DSL
    {
        template <typename T>
        class GTreeNode : public TreeNode<T>
        {
        public:
            LinkList<GTreeNode<T>*> m_GTreeNode;
            static GTreeNode<T>* NewNode() // 工厂模式
            {
                GTreeNode<T>* ret = new GTreeNode<T>();
                if(ret != NULL)
                {
                    ret->m_flag = ture; // 标识堆空间申请的对象
                }
            }
        };
    }
    
    #endif
    GTreeNode.h
    #ifndef GTREE_H
    #define GTREE_H
    
    #include"Tree.h"
    #include"GTreeNode.h"
    #include"Exception.h"
    #include"LinkListQueue.h"
    
    namespace DSL
    {
        template <typename T>
        class GTree : public Tree<T>
        {
            LinkListQueue<GTreeNode<T>*> m_queue; // 实现节点顺序存储
            
        protected:
            GTreeNode<T>* find(GTreeNode<T>* root, const T& value) const
            {
                GTreeNode<T>* ret = NULL;
                
                if(root != NULL)
                {
                    if(value == root->value)
                    {
                        return root;
                    }
                    else
                    {
                        for(root->m_GTreeNode.move(0); !root->m_GTreeNode.end() && (ret == NULL); root->m_GTreeNode.next())
                        {
                            find(root->m_GTreeNode.current(),value);
                        }
                    }
                }
                return ret;
            }
    
            GTreeNode<T>* find(GTreeNode<T>* root, GTreeNode<T>* node) const
            {
                GTreeNode<T>* ret = NULL;
                
                if(root == node)
                {
                    return root;
                }
                else
                {
                    if(root != NULL)
                    {
                        for(root->m_GTreeNode.move(0); !root->m_GTreeNode.end() && (ret == NULL); root->m_GTreeNode.next())
                        {
                            find(root->m_GTreeNode.current(), node);
                        }
                    }
                }
                return ret;
            }
    
            void free(GTreeNode<T>* root)
            {
                if(root == NULL)
                {
                    return;
                }
                else
                {
                    for(root->m_GTreeNode.move(0); !root->m_GTreeNode.end(); root->m_GTreeNode.next())
                    {
                        free(root->m_GTreeNode.current());
                    }
                    if(root->flag())
                    {
                        delete root;
                    }
                }
            }
    
            int count(GTreeNode<T>* node) const
            {
                int ret = 0;
                if(node == NULL)
                {
                    return ret;
                }
                else
                {
                    ret = 1; // 加上根节点的
                    for(node->m_GTreeNode.move(0); !node->m_GTreeNode.end(); node->m_GTreeNode.next())
                    {
                        ret = ret + count(node->m_GTreeNode.current());
                        // return count(node->m_GTreeNode.current()) + 1; // 1 当前根节点
                        // ret = 1 + count(node->m_GTreeNode.current());
                    }
                }
                return ret;
            }
    
            int height(GTreeNode<T>* node) const
            {
                int ret = 0;
                if(node == NULL)
                {
                    return ret;
                }
                else
                {
                    for(node->m_GTreeNode.move(0); !node->m_GTreeNode.end(); node->m_GTreeNode.next())
                    {
                        int h = height(node->m_GTreeNode.current());
                        if(h < ret)
                        {
                            h = ret;
                        }
                    }
                    ret = ret + 1; // 子树全部遍历一次,则已知高度加1
                }
            }
    
            int degree(GTreeNode<T>* node) const
            {
                int ret = 0;
                if(node == NULL)
                {
                    return ret;
                }
                else
                {
                    ret = node->m_GTreeNode.length();
                    for(node->m_GTreeNode.move(0); !node->m_GTreeNode.end(); node->m_GTreeNode.next())
                    {
                        int temp = degree(node->m_GTreeNode.current());
                        if(temp > ret)
                        {
                            ret = temp;
                        }
                    }
                }
                return ret;
            }
    
            
        public:
            GTree() {}
            
            bool insert(TreeNode<T>* node)
            {
                bool ret = ture;
                if(node != NULL)
                {
                    if(this->m_root == NULL)
                    {
                        node->parent = NULL;
                        this->m_root = node;
                    }
                    else
                    {
                        GTreeNode<T>* parent_node = find(node->parent);
                        if(parent_node != NULL)
                        {
                            // parent_node->m_GTreeNode.insert() 下面可避免重复插入树中有的节点
                            GTreeNode<T>* temp_node = dynamic_cast<GTreeNode<T>*>(node);                        
                            if(parent_node->m_GTreeNode.find(temp_node) < 0)
                            {
                                parent_node->m_GTreeNode.insert(temp_node);
                            }
                        }
                        else
                        {
                            ret = false;
                        }
                    }
                }
                else
                {
                    THROW_EXCEPTION(InvalidParameterException, "insert node is NULL!");
                }
                return ret;
            }
            
            bool insert(const T& value, TreeNode<T>* parent)
            {
                bool ret = ture;
                GTreeNode<T>* temp_node = GTreeNode<T>::NewNode();
                if(temp_node != NULL)
                {
                    temp_node->value = value;
                    temp_node->parent = parent;
                    insert(temp_node);
                }
                else
                {
                    THROW_EXCEPTION(InvalidOperationException, "no enough memory to create a node!");
                }
                return ret;
             }
            
            SharedPointer<Tree<T>> remove(TreeNode<T>* node)
            {
                GTree<T>* del_tree;
                if(del_tree == NULL)
                {
                    THROW_EXCEPTION(NotEnoughMemoryException, "no enough memory to create new tree!");
                }
                else
                {
                    GTreeNode<T>* del_node = dynamic_cast<GTreeNode<T>*>(find(node));
                    if(del_node != NULL)
                    {
                        if(root() == del_node)
                        {
                            this->m_root = NULL;
                        }
                        else
                        {
                            LinkList<GTreeNode<T>*>& par_node_list = dynamic_cast<GTreeNode<T>*>(del_node->parent)->m_GTreeNode;                    
                            par_node_list.remove(par_node_list.find(del_node));
                            del_node->parent = NULL;
                            m_queue.clear();
                        }
                    }
                    else
                    {
                        THROW_EXCEPTION(InvalidParameterException, "can not find a node by value!");
                    }
                    del_tree->m_root = del_node;
                    return del_tree;
                }
            }
    
                
            SharedPointer<Tree<T>> remove(const T& value)
            {
                GTree<T>* del_tree;
                if(del_tree == NULL)
                {
                    THROW_EXCEPTION(NotEnoughMemoryException, "no enough memory to create new tree!");
                }
                else
                {
                    GTreeNode<T>* del_node = find(value);
                    if(del_node != NULL)
                    {
                        if(root() == del_node)
                        {
                            this->m_root = NULL;
                        }
                        else
                        {
                            LinkList<GTreeNode<T>*>& par_node_list = dynamic_cast<GTreeNode<T>*>(del_node->parent)->m_GTreeNode;                    
                            par_node_list.remove(par_node_list.find(del_node));
                            del_node->parent = NULL;
                            m_queue.clear();
                        }
                    }
                    else
                    {
                        THROW_EXCEPTION(InvalidParameterException, "can not find a node by value!");
                    }
                    del_tree->m_root = del_node;
                    return del_tree;
                }
            }
            
            GTreeNode<T>* find(TreeNode<T>* node) const
            {
                return find(root(), dynamic_cast<GTreeNode<T>*>(node));
            }
            
            GTreeNode<T>* find(const T& value) const
            {
                return find(root(), value);
            }
            
            GTreeNode<T>* root() const
            {
                return dynamic_cast<GTreeNode<T>*>(this->m_root);
            }
            
            int degree() const
            {
                return degree(root());
            }
            
            int count() const
            {
                return count(root());
            }
            
            int height() const
            {
                return height(root());
            }
    
            /*
            * 实现树按照横向层次来遍历:通过队列头返回一个节点时,将其子节点全部插入队列尾部实现树的顺序存储和读取。
            * begin()   
            * next()    
            * current() 
            * end()     
            */
            bool begin()  // 根节点压入队列
            {
                if(root() == NULL)
                {
                    return false;
                }
                else
                {
                    m_queue.clear();
                    m_queue.add(root());
                    return ture;
                }
            }
    
            bool next() // 弹出队头元素,将队头节点孩子压入队列
            {
                if(m_queue.length() <= 0)
                {
                    return false;
                }
                else
                {
                    GTreeNode<T>* node = m_queue.front();
                    m_queue.remove();
                    for(node->m_GTreeNode.move(0); !node->m_GTreeNode.end(); node->m_GTreeNode.next())
                    {
                        m_queue.add(node->m_GTreeNode.current());
                    }
                    return ture;            
                }
            }
    
            T current()  // 访问队头元素指向节点的数据
            {
                if(!end())
                {
                    return m_queue.front()->value;
                }
                else
                {
                    THROW_EXCEPTION(InvalidOperationException, "index out of bound!");
                }
            
    }
    
            bool end()
    
            {
                return (m_queue.length() != 0);
            }
            
            void clear()
            {
                free(root());
                this->m_root = NULL;
                m_queue.clear();
            }
    
            ~GTree()
            {
                clear();
            }
        };
    }
    
    #endif
    GTree.h

    孩子兄弟表示法:

      a. 每个节点都有指向第一个孩子的指针

      b. 每个节点都有指向第一个右兄弟的指针

       优点:每个节点只有两个指针和一个数据,节点总类只有五种,但是可以描述任意类型的树形结构,形象称为二叉树

     二叉树:由一个根节点和两棵树组成,称为左子树和右子树.

       满二叉树: 二叉树中所有分支节点度数都为2,且叶子节点都在同一层次上.

      完全二叉树:一个二叉树的已有的节点在位置上和高度相同的满二叉树在位置编号(层次遍历编号)上一一对应.(一颗具有n个节点高度为k的二叉树,每一个节点和高度为k的满二叉树中的编号为1 -- n节点一一对应)

         特点: 同样节点数的二叉树中完全二叉树高度最小.完全二叉树叶节点只出现在最下面两层. 最底层叶节点一定在左边.倒数第二层叶节点一定在右边.完全二叉树度为一的节点只有左孩子

     二叉树特点:

      1. 在二叉树的第 i 层最多有 2^(i-1) 个节点

      2. 高度为k的二叉树一共最多有2^k - 1个节点

      3. 任意一颗二叉树,叶节点有n0个,度为2的非叶节点有n2个, n0 = n2 + 1

      4. 具有n个节点的完全二叉树的高度为[log2n]+1. ([X]表示不大于X的最大整数) 

      5. 一棵n个节点的完全二叉树,按照层次编号(先从上到下再从左到右),对于任意节点i有以下父子关系:

          a.  i = 0, 节点i表示二叉树的根. i > 1, 双亲节点为[i/2]

          b.  2i < n,节点i的左孩子为2i. 2i > n 节点i无左孩子

          c.  2i + 1 <= n 节点i的右孩子为2i + 1. 2i + 1 > n节点i无右孩子

    遍历:

      层次遍历:从上到下从左到右

      先序遍历:根节点在开始位置被访问

      中序遍历:根节点在中间位置被访问

      后序遍历:根节点在最后位置被访问

    #ifndef BTREENODE_H
    #define BTREENODE_H
    
    #include"TreeNode.h"
    
    namespace DSL
    {
        template <typename T>
        class BTreeNode : public TreeNode<T>
        {
        public:
            BTreeNode<T>* left_child;
            BTreeNode<T>* right_child;
    
            BTreeNode()
            {
                left_child = NULL;
                right_child = NULL;
            }
        
            static BTreeNode<T>* NewNode()
            {
                BTreeNode<T>* ret = new BTreeNode<T>();
                if(ret != NULL)
                {
                    ret->m_flag = ture;
                }
            }
        };
        enum ChildDirect
        {
            ANY_DIR,
            LEFT_DIR,
            RIGHT_DIR
        };
    }
    
    #endif
    BTreeNode.h
    #ifndef BTREE_H
    #define BTREE_H
    
    #include"Tree.h"
    #include"BTreeNode.h"
    #include"Exception.h"
    #include"LinkListQueue.h"
    #include"SharedPointer.h"
    #include"DynamicArray.h"
    
    namespace DSL
    {
        enum TraversalType
        {
            PREORDER,
            INORDER,
            POSORDER,
            LEVELORDER
        };
        
        template <typename T>
        class BTree : public Tree<T>
        {
        protected:
            LinkListQueue<BTreeNode<T>*> m_queue;
        
            virtual BTreeNode<T>* find(BTreeNode<T>* root, const T& value) const
            {
                BTreeNode<T>* ret = NULL;
                if(root != NULL)
                {
                    if(root->value == value)
                    {
                        ret = root;
                    }
                    else
                    {
                        if(ret == NULL)
                        {
                            find(root->left_child, value);
                        }
                        if(ret == NULL)
                        {
                            find(root->right_child, value);
                        }
                    }
                }
                return ret;
            }
    
            virtual BTreeNode<T>* find(BTreeNode<T>* root, BTreeNode<T>* node) const
            {
                BTreeNode<T>* ret = NULL;
                if(root == node)
                {
                    ret = node;
                }
                else
                {
                    if(root != NULL)
                    {
                        if(ret == NULL)
                        {
                            find(root->left_child, node);
                        }
                        if(ret == NULL)
                        {
                            find(root->right_child, node);
                        }
                    }
                }
                return ret;
            }
    
            virtual bool insert(BTreeNode<T>* node_parent, BTreeNode<T>* node, ChildDirect direct)
            {
                bool ret = ture;
                if(direct == ANY_DIR)
                {
                    if(node_parent->left_child == NULL)
                    {
                        node_parent->left_child = node;
                    }
                    else if(node_parent->right_child == NULL)
                    {
                        node_parent->right_child = node;
                    }
                    else
                    {
                        ret = false;
                    }
                }
                else if(direct == LEFT_DIR)
                {
                    if(node_parent->left_child == NULL)
                    {
                        node_parent->left_child = node;
                    }
                    else
                    {
                        ret = false;
                    }
                }
                else if(direct == RIGHT_DIR)
                {
                    if(node_parent->right_child == NULL)
                    {
                        node_parent->right_child = node;
                    }
                    else
                    {
                        ret = false;
                    }                
                }
                else
                {
                    ret = false;
                }
                return ret;
            }
    
            virtual void remove(BTreeNode<T>* node, BTree<T>*& ret)
            {
                ret = new BTree<T>();
                if(ret == NULL)
                {
                    THROW_EXCEPTION(NotEnoughMemoryException, "no enough memory to allocate a tree!");
                }
                else
                {
                    BTreeNode<T>* node_parent = dynamic_cast<BTreeNode<T>*>(node->parent);
                    if(node_parent->left_child == node)
                    {
                        node_parent->left_child = NULL;    
                    }
                    else if(node_parent->right_child == node)
                    {
                        node_parent->right_child = NULL;
                    }
                    node->parent = NULL;
                }
                ret->m_root = node;
            }
    
            virtual void free(BTreeNode<T>* del_node)
            {
                if(del_node ==NULL)
                {
                    return;
                }
                else
                {
                    free(del_node->left_child);
                    free(del_node->right_child);
                    if(del_node->flag())
                    {
                        delete del_node;
                    }
                }
            }
    
            int count(BTreeNode<T>* root) const
            {
                int ret = 0;
                if(root == NULL)
                {
                    return ret;
                }
                else
                {
                    return (count(root->left_child) + count(root->right_child) + 1); // 1为当前根节点
                }
                // return ((root != NULL) ? (count(root->left_child) + count(root->right_child) + 1) : 0);
            }
    
            int height(BTreeNode<T>* root) const
            {
                int ret = 0;
                if(root == NULL)
                {
                    return ret;
                }
                else
                {
                    int left_height = count(root->left_child);
                    int right_height = count(root->right_child);
                    if(left_height > right_height)
                    {
                        ret = left_height + 1; // 1为当前根节点个数
                    }
                    return ret;
                    // return (((left_height > right_height) ? left_height : right_height) + 1);
                }
            }
    
            int degree(BTreeNode<T>* root) const
            {
                int ret = 0;
                if(root == NULL)
                {
                    return ret;
                }
                else
                {
                    int degree_root = (!!root->left_child) + (!!root->right_child);
                    if(ret < 2)
                    {
                        int degree_left = degree(root->left_child);
                        if(degree_left > degree_root)
                            ret = degree_left;
                    }
                    if(ret < 2)
                    {
                        int degree_right = degree(root->right_child);
                        if(degree_right > degree_root)
                            ret = degree_right;
                    }
                    return ret;
                }
            
            /*
                int ret = 0;
                if(root == NULL)
                {
                    return ret;
                }
                else
                {
                    int degree_left = degree(root->left_child);
                    int degree_right = degree(root->right_child);
                    int degree_root = (!!root->left_child) + (!!root->right_child);
                    if(degree_left > degree_root)
                    {
                        ret = degree_left;
                    }
                    if(degree_right > degree_root)
                    {
                        ret = degree_right;
                    }
                    if(degree_left > degree_right)
                    {
                        ret = degree_left;
                    }
                    return ret;
                }
            */
            }
    
            
            // 先序遍历:根节点在开始位置被访问
            void PreOrderTraversal(BTreeNode<T>* root, LinkListQueue<BTreeNode<T>*>& queue)
            {
                if(root == NULL)
                {
                    return;
                }
                else
                {
                    queue.add(root);
                    PreOrderTraversal(root->left_child, queue);
                    PreOrderTraversal(root->right_child, queue);
                }
            }
    
            //中序遍历:根节点在中间位置被访问
            void InOrderTraversal(BTreeNode<T>* root, LinkListQueue<BTreeNode<T>*>& queue)
            {
                if(root == NULL)
                {
                    return;
                }
                else
                {
                    InOrderTraversal(root->left_child, queue);
                    queue.add(root);
                    InOrderTraversal(root->right_child, queue);
                }
            }
    
            //后序遍历:根节点在最后位置被访问
            void PostOrderTraversal(BTreeNode<T>* root, LinkListQueue<BTreeNode<T>*>& queue)
            {
                if(root == NULL)
                {
                    return;
                }
                else
                {
                    PostOrderTraversal(root->left_child, queue);
                    PostOrderTraversal(root->right_child, queue);
                    queue.add(root);
                }
            }
    
            //层次遍历:从上到下从左到右。第一个队列完成层次次序的访问,第二个队列保存访问次序
            void LevelOrderTraversal(BTreeNode<T>* root, LinkListQueue<BTreeNode<T>*>& ret_queue)
            {
                if(root == NULL)
                {
                    THROW_EXCEPTION(InvalidParameterException, "can not convert a empty tree!");
                }
                else
                {
                    LinkListQueue<BTreeNode<T>*> temp_queue;
                    BTreeNode<T>* temp_node;
                    temp_queue.add(root);
                    while(temp_queue.length() > 0)
                    {
                        temp_node = temp_queue.front();                
                        if(temp_node->left_child)
                        {
                            temp_queue.add(temp_node->left_child);
                        }
                        if(temp_node->right_child)
                        {
                            temp_queue.add(temp_node->right_child);
                        }
                        temp_queue.remove();
                        ret_queue.add(temp_node);
                    }
                }
            }
    
            BTreeNode<T>* clone(const BTreeNode<T>* node) const
            {
                BTreeNode<T>* temp_node = NULL;
                if(node == NULL)
                {
                    return NULL;
                }
                else
                {
                    if(temp_node == NULL)
                    {
                        THROW_EXCEPTION(NotEnoughMemoryException, "can not create new node!");
                    }
                    else
                    {
                        temp_node->value = node->value;
                        temp_node->left_child = clone(node->left_child);
                        temp_node->right_child = clone(node->right_child);
                        // 初始化每个节点parent指针
                        if(temp_node->left_child)
                        {
                        
        temp_node->left_child->parent = temp_node;
                        }
                        if(temp_node->right_child)
                        {
                            temp_node->right_child->parent = temp_node;
                        }
                    }
                }
    
            }
    
            bool equal(BTreeNode<T>* left_tree, BTreeNode<T>* right_tree) const
            {
                if(left_tree == right_tree)
                {
                    return ture;
                }
                else if((left_tree != NULL) && (right_tree != NULL))
                {
                    return ((left_tree->value == right_tree->value) && (equal(left_tree->left_child, right_tree->left_child)) && (equal(left_tree->right_child, right_tree->right_child)));
                }
                else // 一棵二叉树为空,一颗二叉树不为空
                {
                    return false;
                }
            }
    
            BTreeNode<T>* add(BTreeNode<T>* tree1_root, BTreeNode<T>* tree2_ndoe) const
            {
                BTreeNode<T>* temp_node = NULL;
                if((tree1_root == NULL) && (tree2_ndoe != NULL))
                {
                    return clone(tree2_ndoe);
                }
                else if((tree1_root != NULL) && (tree2_ndoe == NULL))
                {
                    return clone(tree1_root);
                }
                else if((tree1_root != NULL) && (tree2_ndoe != NULL))
                {
                    temp_node = BTreeNode<T>::NewNode();
                    if(temp_node == NULL)
                    {
                        THROW_EXCEPTION(NotEnoughMemoryException, "no enought memory to create new node!");
                    }
                    else
                    {
                        temp_node->value = tree1_root->value + tree2_ndoe->value;
                        temp_node->left_child = add(tree1_root->left_child,tree2_ndoe->left_child);
                        temp_node->right_child = add(tree1_root->right_child, tree2_ndoe->right_child);
                        // 初始化每个节点parent指针
                        if(temp_node->left_child)
                        {
                        
        temp_node->left_child->parent = temp_node;
                        }
                        if(temp_node->right_child)
                        {
                            temp_node->right_child->parent = temp_node;
                        }
                    }
                }
                else // 两棵树都为空
                {
                    return NULL;
                }
            }
    
            // 线索化STEP1:将输入的树root转化根据遍历类型type遍历并将其按照遍历顺序存放在ret_queue队列中
            void traversal(BTreeNode<T>* root, LinkListQueue<BTreeNode<T>*>& ret_queue, TraversalType type)
            {
                switch (type)
                {
                    case PREORDER:
                        PreOrderTraversal(root, ret_queue);
                        break;
                    case INORDER:
                        InOrderTraversal(root, ret_queue);
                        break;
                    case POSORDER:
                        PostOrderTraversal(root, ret_queue);
                        break;
                    case LEVELORDER:
                        LevelOrderTraversal(root, ret_queue);
                        break;
                    default:
                        THROW_EXCEPTION(InvalidParameterException, "unknown traversal type!");
                        break;
                }
            }
    
            //线索化STEP2:将输入节点为树节点的queue转化为双向链表,并返回双向链表头节点
            //             连接队列中的节点(right指向后继,left指向前驱)形成双向链表
            BTreeNode<T>* connect(LinkListQueue<BTreeNode<T>*>& queue)
            {
                BTreeNode<T>* list_head = NULL, slider = NULL;
                if(queue == NULL && queue.length() > 0)
                {
                    return NULL;
                }
                else
                {
                    list_head = queue.front();
                    slider = queue.front();
                    queue.remove();
                    slider->left_child = NULL;
                    while(queue.length() > 0)
                    {
                        slider->right_child = queue.front();
                        queue.front()->right_child = slider;
                        slider = queue.front();
                        queue.remove();
                    }
                    slider->right_child = NULL;
                }
                return list_head;
            }
            
        public:
            bool insert(TreeNode<T>* node)
            {
                return insert(node, ANY_DIR);
            }
    
            bool insert(TreeNode<T>* node, ChildDirect direct)
            {
                bool ret = ture;
                if(node != NULL)
                {
                    if(this->m_root == NULL)
                    {
                        node->parent = NULL;
                        this->m_root = node;
                    }
                    else
                    {
                        BTreeNode<T>* node_parent = find(node->parent);
                        if(node_parent != NULL)
                        {
                            if(!insert(dynamic_cast<BTreeNode<T>*>(node), node_parent, direct))
                            {
                                ret = false;
                            }
                        }
                        else
                        {
                            ret = false;
                        }
                    }
                }
                else
                {
                    THROW_EXCEPTION(InvalidParameterException, "insert node is NULL!");
                }
                return ret;
            }
            
            bool insert(const T& value, TreeNode<T>* parent)
            {
                return insert(value, parent, ANY_DIR);            
            }
    
            bool insert(const T& value, TreeNode<T>* parent, ChildDirect direct)
            {
                bool ret = ture;
                BTreeNode<T>* temp_node = BTreeNode<T>::NewNode();
                if(temp_node != NULL)
                {
                    temp_node->value = value;
                    temp_node->parent = parent;
                    if(!insert(temp_node, direct))
                    {
                        delete temp_node;
                        ret = false;
                    }
                }
                else
                {
                    THROW_EXCEPTION(InvalidParameterException, "can not allcote new node!");
                }
                return ret;
            }
            
            SharedPointer<Tree<T>> remove(TreeNode<T>* node)
            {
                BTree<T>* ret_tree = NULL;
                node = find(node);
                if(node == NULL)
                {
                    THROW_EXCEPTION(InvalidParameterException, "remove node is not in tree!");
                }
                else
                {
                    remove(dynamic_cast<BTreeNode<T>*>(node), ret_tree);
                    m_queue.clear(); //清空队列;
                }
                return ret_tree;
            }
            
            SharedPointer<Tree<T>> remove(const T& value)
            {
                BTree<T>* ret_tree = NULL;
                BTreeNode<T>* node = find(value);
                if(node == NULL)
                {
                    THROW_EXCEPTION(InvalidParameterException, "remove node is not in tree!");
                }
                else
                {
                    remove(node, ret_tree);
                    m_queue.clear(); //清空队列;
                }
                return ret_tree;
            }
            
            BTreeNode<T>* find(TreeNode<T>* node) const
            {
                return find(root(), dynamic_cast<BTreeNode<T>*>(node));
            }
            
            BTreeNode<T>* find(const T& value) const
            {    
                return find(root(), value);
            }
            
            BTreeNode<T>* root() const
            {
                return dynamic_cast<BTreeNode<T>*>(this->m_root);
            }
            
            int degree() const
            {
                return degree(root());
            }
            
            int count() const
            {
                return count(root());
            }
            
            int height() const
            {
                return height(root());
            }
    
            // 二叉树的层次遍历
            bool begin()
            {
                if(root() == NULL)
                {
                    return false;
                }
                else
                {
                    m_queue.clear();
                    m_queue.add(root());
                    return ture;
                }
            }
            
            bool next()
            {
                if(m_queue.length() <= 0)
                {
                    return false;
                }
                else
                {
                    BTreeNode<T>* head_node = m_queue.front();
                    m_queue.remove();
                   if(head_node->left_child) 
                    {
                        m_queue.add(head_node->left_child); 
                       }
                       if(head_node->right_child) 
                    {
                        m_queue.add(head_node->right_child); 
                       }
                    return ture;
                }
            }
            
            bool end()
            {
                return (m_queue.length() == 0);
            }
            
            T current()
            {
                if(end())
                {    
                    THROW_EXCEPTION(InvalidOperationException, "index out of bound!");
                }
                else
                {
                    return m_queue.front()->value;
                }
            }
    
            // 二叉树的先序,中序,后续遍历
            SharedPointer<DynamicArray<T>> traversal(BTreeNode<T>* root, TraversalType type)
            {
                LinkListQueue<BTreeNode<T>*> queue;
                DynamicArray<T>* array = NULL;
            
                if(root() == NULL)
                {
                    THROW_EXCEPTION(InvalidOperationException, "empty tree can not be traversaled!");
                }
                else
                {
                    traversal(root, queue, type);
                    array = new DynamicArray<T>(queue.length());
                    if(array == NULL)
                    {
                        THROW_EXCEPTION(NotEnoughMemoryException, "no enough to create a new array!");
                    }
                    else
                    {
                        for(int i = 0; i < array.length(); i++, queue.remove())
                        {
                            array.set(i, queue.front()->value);
                        }
                    }
    
                }
            }
    
            //拷贝根节点为tree_root的二叉树
            SharedPointer<Tree<T>>* clone(BTreeNode<T>* tree_root) const
            {
                BTree<T>* temp_tree = new BTree<T>();
                if(temp_tree == NULL)
                {
                    THROW_EXCEPTION(NotEnoughMemoryException, "no enough memory to create tree!");
                }
                else
                {
                    temp_tree->m_root = clone(tree_root);
                }
                return temp_tree;
            }
    
            //对二叉树每个元素进行比较
            bool operator == (const BTree<T>* tree) const
            {
                return equal(root(), tree.root());
            }
    
            bool operator != (const BTree<T>* tree) const
            {
                return !(*this == tree);
            }
    
            //二叉树相加操作,将当前二叉树与参数树在对应节点的数值相加
            //返回值是堆空间申请的新二叉树
            SharedPointer<BTree<T>> add(const BTree<T>&  btree) const
            {
                BTree<T>* temp_tree = new BTree<T>();
                if(temp_tree == NULL)
                {
                    THROW_EXCEPTION(NotEnoughMemoryException, "no enough memory to create a new tree!");
                }
                else
                {    
                    temp_tree->m_root = add(root(), btree.root());
                }
                return temp_tree;
            }
    
            // 线索化二叉树:将二叉树转化成双向链表。
            BTreeNode<T>* threaded(BTree<T>* tree, TraversalType type)
            {
                if(root == NULL)
                {
                    return NULL;
                }
                else
                {
                    BTreeNode<T>* list_head = NULL;
                    LinkListQueue<BTreeNode<T>*> queue = NULL;
                    traversal(tree.root(), queue, LEVELORDER);
                    list_head = connect(queue);
                    tree.m_root = NULL;
                    tree.clear();
                    return list_head;
                }
            }
    
            // 删除树根节点为root中的单度节点
            BTreeNode<T>* delete_single_drgree_node(BTreeNode<T>* root)
            {
                BTreeNode<T>* head = NULL;
                if(root == NULL)
                {
                    return NULL;
                }
                else
                {
                    if(((root->left_child == NULL) && (root->right_child != NULL)) || ((root->left_child != NULL) && (root->right_child ==NULL)))// 单度情况
                    {
                        BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(root->parent);
                        BTreeNode<T>* child = ((root->left_child != NULL) ? root->left_child : root->right_child);
                        if(parent != NULL)
                        {
                            ((parent->left_child != NULL) ? parent->left_child : parent->right_child) = child; // C++三目运算表达式返回变量本身
                            child->parent = parent;
                        }
                        if(parent == NULL) // 处理根节点就是单度节点的情况
                        {
                            child->parent = NULL;
                        }
                        if(root->flag())
                        {
                            delete root;
                        }
                        head = delete_single_drgree_node(child);
                    }
                    else // 考虑度为0或2的情况 
                    {
                        delete_single_drgree_node(root->left_child);
                        delete_single_drgree_node(root->right_child);
                        head = root;
                    }
                }
                return head;
            }
    
            // 删除树根节点为root中的单度节点,返回根节点为root的树, 没有父节点
            void delete_single_drgree_node(BTreeNode<T>*& root)
            {
                if(root == NULL)
                {
                    THROW_EXCEPTION(InvalidParameterException, "can not do delete single degree node for empty tree!");
                }
                else
                {
                    if(((root->left_child != NULL) && (root->right_child ==NULL)) || ((root->left_child == NULL) && (root->right_child != NULL)))
                    {
                        BTreeNode<T>* child = ((root->left_child != NULL) ? root->left_child : root->right_child);
                        if(root->flag())
                            delete root;
                        root = child;
                        delete_single_drgree_node(root);
                    }
                    else
                    {
                        delete_single_drgree_node(root->left_child);
                        delete_single_drgree_node(root->right_child);
                    }
                }
            }
    
            // 中序遍历并直接线索化
            // pre指针指向中序访问时前驱结点,root指向中序访问节点
            void inorderthreaded(BTreeNode<T>* root_node, BTreeNode<T>*& pre_node)
            {
                if(root_node ==NULL)
                {
                    return ;
                }
                else
                {
                    inorderthreaded(root_node->left_child, pre_node); // 这里返回后代表左子树线索化完毕,pre_node指向链表的最后一个节点
                    root_node->left_child = pre_node;
                    if(pre_node != NULL)
                    {
                         pre_node->right_child = root_node;
                    }
                    pre_node = root_node;
                    inorderthreaded(root_node->right_child, pre_node);
                    return ;
                }
            }
    
            // 中序遍历线并直接索化
            // 中序遍历节点的次序是节点的水平次序 head_node转换完成后的头节点,tail_node指向尾节点
            void inorderthreaded(BTreeNode<T>* root_node, BTreeNode<T>*& head_node, BTreeNode<T>*& tail_node)
            {
                if(root_node == NULL)
                {
                    return;
                }
                else
                {
                    BTreeNode<T>* head = NULL;
                    BTreeNode<T>* tail = NULL;
                    inorderthreaded(root_node->left_child, head, tail);
                    root_node->left_child = tail;
                    if(tail != NULL)
                        tail->right_child = root_node;
                    head_node = ((head != NULL) ? head : root_node);
                    head = NULL;
                    tail = NULL;
                    
                    inorderthreaded(root_node->right_child ,head, tail);
                    root_node->right_child = head;
                    if(head != NULL)
                        head->left_child = root_node;
                    tail_node = ((tail != NULL) ? tail : root_node);
                }
            }
            
            void clear()
            {
                free(root());
                m_queue.clear(); //清空队列;
                this->m_root = NULL;
            }
    
            ~BTree()
            {
                clear();
            }
        };
    }
    
    #endif
    BTree.h
  • 相关阅读:
    解决在SQLPLUS中无法使用方向键、退格键问题
    Oracle 11g R2手动配置EM(转)
    为什么JDK代码这样写?final ReentrantLock takeLock = this.takeLock
    使用CompletableFuture实现业务服务的异步调用实战代码
    SpringBoot项目从Git拉取代码并完成编译打包启动的sh自动脚本
    SpringBoot项目实现配置实时刷新功能
    (8)Flask微电影项目会员中心其他页面搭建
    (7)Flask微电影之会员中心页面搭建
    (6)Flask项目之会员注册页面
    (5)Flask项目会员登录页
  • 原文地址:https://www.cnblogs.com/zsy12138/p/12501678.html
Copyright © 2011-2022 走看看