• C++二叉查找树实现及转化为双向链表


    二叉树首先要有树节点

    template<class T>
    class BinaryNode
    {
    public:
        T element;
        BinaryNode *left;
        BinaryNode *right;
    
    public:
        BinaryNode(T passelement);
        ~BinaryNode();
    };
    
    template<class T>
    BinaryNode<T>::BinaryNode(T passelement)
    {
        this->element=passelement;
        this->left=NULL;
        this->right=NULL;
    }
    
    template<class T>
    BinaryNode<T>::~BinaryNode()
    {
    }

    二叉树对象则比较复杂

     template<class T>
    class BinarySearchTree
    {
    private:
        BinaryNode<T> *m_proot;
    public:
        const T findMin() const;//获取最小值
        const T findMax() const;//获取最大值
        bool contains(const T& xele) const;//判断是否包含
        void makeEmpty();//清空二叉树
        void insert(const T& xele);//插入
        void remove(const T& xele);//删除
        void inordertrav();//中序遍历
        void toDoublelist();//转化为双向链表
        void printDoublelist();//打印双向链表
    public://构造与析构函数
        BinarySearchTree();
        BinarySearchTree(const BinarySearchTree& bst);
        ~BinarySearchTree();
    private://全部用于递归调用
        void makeEmpty(BinaryNode<T>* &t);
        const T findMin(BinaryNode<T>* &t);
        void remove(const T& xele, BinaryNode<T>* &t);
        void insert(const T& xele, BinaryNode<T>* &t);
        void inordertrav(BinaryNode<T>* &t);
        void toDoublelist(BinaryNode<T>* &t);
        BinaryNode<T>* getlLeftTail(BinaryNode<T>* &t);//获取左子树的最大节点
        BinaryNode<T>* getlRightHead(BinaryNode<T>* &t);//获取右子树的最小节点
    };

    具体函数实现如下:

    1.判断是否包含:

    template<class T>
    bool BinarySearchTree<T>::contains(const T& xele) const
    {
        BinaryNode<T>* pcurrent = m_proot;
        while (true)
        {
            if (pcurrent == NULL)//指针为空
            {
                return false;
            }
            else if (xele < pcurrent->element)
                pcurrent = pcurrent->left;
            else if (xele > pcurrent->element)
                pcurrent = pcurrent->right;
            else
            {
                pcurrent = NULL;
                return true;
            }
        }
    
    }

    2.返回最小值:

    template<class T>
    const T BinarySearchTree<T>::findMin() const
    {
        BinaryNode<T>* m_pcurrent = m_proot;
        while (m_pcurrent->left != NULL)
        {
            m_pcurrent = m_pcurrent->left;
        }
        return m_pcurrent->element;
    }

    或:

    template<class T>
    const T BinarySearchTree<T>::findMin(BinaryNode<T>* &t)
    {
        if (t == NULL)
            return NULL;
        if (t->left == NULL)
            return t->element;
        else
            return findMin(t->left);
    
    }
    template<class T>
    const T BinarySearchTree<T>::findMin()
    {
           findMin(m_proot);
    }

    3.返回最大值:

    template<class T>
    const T BinarySearchTree<T>::findMax() const
    {
        BinaryNode<T>* m_pcurrent = m_proot;
        while (m_pcurrent->right != NULL)
        {
            m_pcurrent = m_pcurrent->right;
        }
        return m_pcurrent->element;
    }

    4.清空:

    template<class T>
    void  BinarySearchTree<T>::makeEmpty(BinaryNode<T>* &t)
    {
        if (t!=NULL)
        {
            makeEmpty(t->left);
            makeEmpty(t->right);
            delete t;
        }
        t = NULL;
    }
    template<class T>
    void BinarySearchTree<T>::makeEmpty()
    {
        makeEmpty(m_proot);
    }

    5.插入:

    template<class T>
    void BinarySearchTree<T>::insert(const T& xele, BinaryNode<T>* &t)
    {
        if (t == NULL)
            t = new BinaryNode<T>(xele);
        else if (xele < t->element)
            return insert(xele, t->left);
        else if (xele > t->element)
            return insert(xele, t->right);
        else
            ;
    }
    template<class T>
    void BinarySearchTree<T>::insert(const T& xele)
    {
        insert(xele, m_proot);
    }

    6.删除:

    template<class T>
    void BinarySearchTree<T>::remove(const T& xele, BinaryNode<T>* &t)
    {
        if (t == NULL)
            return;
        else if (xele < t->element)
            remove(xele, t->left);
        else if (xele > t->element)
            remove(xele, t->right);
        else
        {
            if (t->left != NULL&&t->right != NULL)
            {
                t->element = findMin(t->right);
                remove(t->element, t->right);
            }
            else
            {
                BinaryNode<T>* oldNode = t;
                t = (t->left != NULL) ? t->left : t->right;
                delete oldNode;
            }
        }
    }
    template<class T>
    void BinarySearchTree<T>::remove(const T& xele)
    {
        remove(xele, m_proot);
    }

    7.中序遍历:

    template<class T>
    void BinarySearchTree<T>::inordertrav()
    {
        inordertrav(m_proot);
    }
    template<class T>
    void BinarySearchTree<T>::inordertrav(BinaryNode<T>* &t)//参数是根节点
    {
        if (NULL == t)
            return;
        if (NULL != t->left)
            inordertrav(t->left);
        cout << t->element << "," << endl;
        if (NULL != t->right)
            inordertrav(t->right);
    }

    8.转换为双向链表,需要注意的是:不能使用中序遍历的方法去实现转换,这样会引起指针异常;转换后以前操作二叉树的函数全部失效

    template<class T>
    BinaryNode<T>* BinarySearchTree<T>::getlLeftTail(BinaryNode<T>* &t)
    {
        BinaryNode<T>* pC = t;
        while (true)
            if (NULL != pC->right)
                pC = pC->right;
            else
                break;
        return pC;
    }
    template<class T>
    BinaryNode<T>* BinarySearchTree<T>::getlRightHead(BinaryNode<T>* &t)
    {
        BinaryNode<T>* pC = t;
        while (true)
            if (NULL != pC->left)
                pC = pC->left;
            else
                break;
        return pC;
    }
    template<class T>
    void BinarySearchTree<T>::toDoublelist()
    {
        toDoublelist(m_proot);
    }
    template<class T>
    void BinarySearchTree<T>::toDoublelist(BinaryNode<T>* &t)
    {
        
        if (NULL == t)
            return;
        if (NULL != t->left)
        {
            BinaryNode<T>* listtail = getlLeftTail(t->left);//先记录下来要与根节点的左指针相连的。
            toDoublelist(t->left);
            listtail->right = t;
            t->left = listtail;
        }
    
        /*这个方法会出现问题
        //不为空
        if (NULL != m_plist)
        {
            t->left = m_plist;
            m_plist->right = t;
        }
        else//为空表示使双向链表的头
        {
            m_phead = t;
        }
        //为下一次连接做准备
        m_plist = t;
    
        cout << m_plist->element << ",";*/
        
    
        if (NULL != t->right)
        {
            BinaryNode<T>* listhead = getlRightHead(t->right);
            toDoublelist(t->right);
            listhead->left = t;
            t->right = listhead;
            
        }
            
    }

    9.打印链表:

    template<class T>
    void BinarySearchTree<T>::printDoublelist()
    {
        BinaryNode<T>* phead = m_proot;
        while (true)
        {
            if (phead->left != NULL)
                phead = phead->left;
            else
                break;
        }
        while (phead->right!=NULL)
        {
            cout << phead->element << ",";
            phead = phead->right;
        }
        cout << phead->element;
    }
  • 相关阅读:
    力扣(LeetCode)67. 二进制求和
    力扣(LeetCode) 66. 加一
    力扣(LeetCode)58. 最后一个单词的长度
    力扣(LeetCode)1009. 十进制整数的反码
    力扣(LeetCode) 20. 有效的括号
    力扣(LeetCode)1016. 子串能表示从 1 到 N 数字的二进制串
    数据库索引
    OSI 七层和五层
    ST算法
    F
  • 原文地址:https://www.cnblogs.com/WonderHow/p/4431369.html
Copyright © 2020-2023  润新知