线索二叉树和BST

线索化借鉴https://blog.csdn.net/my_heart_/article/details/52086321
搜索树参考 https://www.icourse163.org/learn/ZJU-93001?tid=1003013004#/learn/content?type=detail&id=1004242206&sm=1

#include<iostream>
#include<cstring>
#define ElemType char
using namespace std;
typedef enum{           //枚举?emmm,之前不知道
    Link,
    Thread
}Tag;
typedef struct BiTreeNode{
    BiTreeNode(const ElemType data)
    :Data(data),
    Left(NULL),
    Right(NULL),
    rTag(Link),
    lTag(Link)
    {}
    ElemType Data;
    BiTreeNode*Left,*Right;
    Tag rTag,lTag;
}BiTreeNode;

class Thread_Tree{
    //friend class Binary_Search_Tree;
    public:
        Thread_Tree(const ElemType* arr,size_t Size)
        :pRoot(NULL),
        Prev(NULL)
        {
            size_t index=0;
            _CreateTree(pRoot,arr,Size,index);
        }
    protected:
        void _CreateTree(BiTreeNode*&Root,
            const ElemType*arr,size_t size,size_t&index)//注意Root,index存储改变
        {                                               //取地址
            if(!arr||size==0)
            {
                cout<<"error input"<<endl;
                return;
            }
            if(index<size&&arr[index]!='#')
            {
                Root=new BiTreeNode(arr[index]);            //先序建树
                _CreateTree(Root->Left,arr,size,++index);
                _CreateTree(Root->Right,arr,size,++index);
            }
        }
    public:
        void PreOrderThreading()
        {
            _PreOrderThreading(this->pRoot);
        }
        void PreOrder()
        {
            _PreOrder(this->pRoot);
        }
    protected:
        void _PreOrderThreading(BiTreeNode*&Root)
        {
            if(!Root)return;            //结束条件
            if(!Root->Left)             //没有左子树,Left指向前驱
            {
                Root->Left=Prev;
                Root->lTag=Thread;      //标记Left为线索
            }
            if(Prev&&!Prev->Right)      //前驱存在且没有右子树
            {                           //则Right指向后继
                Prev->Right=Root;
                Prev->rTag=Thread;      //Right为线索
            }
            Prev=Root;                  //作为下一次递归的前驱
            if(Root->lTag==Link)
                _PreOrderThreading(Root->Left);     //左子树存在,线索化左子树
            if(Root->rTag==Link)
                _PreOrderThreading(Root->Right);     //……
        }
        void _PreOrder(BiTreeNode*Root)         //先序遍历
        {
            if(!Root)return;
            auto pCur=Root;
            while(pCur)
            {
                while(pCur->lTag==Link&&pCur->Left)     //打印爸爸,直到最左
                {
                    cout<<pCur->Data<<" ";
                    pCur=pCur->Left;
                }
                cout<<pCur->Data<<" ";          //不要漏下最左边的结点
                if(pCur->lTag==Thread)pCur=pCur->Right;      //最左边完了,往右走
                while(pCur)
                {
                    if(pCur->Left&&pCur->lTag==Link)break;   //如果右边的结点有左子树,
                    cout<<pCur->Data<<" ";                   //退出,遍历该左子树
                    pCur=pCur->Right;
                }
            }
        }
        private:
            BiTreeNode*pRoot,*Prev;
};
class Binary_Search_Tree{
    //friend class Thread_Tree;
    public:
        Binary_Search_Tree()
        :Root(NULL)
        {};
    public:
        BiTreeNode* Find(const ElemType X)
        {
           return  _Find(X,this->Root);
        }
        BiTreeNode* FindMin()
        {
            return _FindMin(this->Root);
        }
        BiTreeNode* FindMax()
        {
            return _FindMax(this->Root);
        }
        void Insert(const ElemType X)
        {
             _Insert(X,this->Root);
        }
        void Delete(const ElemType X)
        {
             _Delete(X,this->Root);
        }
    protected:
        BiTreeNode*_Find(const ElemType X,BiTreeNode*Root)   //BST,左边小于右边
        {                                                    //小于向左边找,
            if(!Root)return NULL;                             //大于向右边找
            else if(X<Root->Data)
                return _Find(X,Root->Left);
            else if(X>Root->Data)
                return _Find(X,Root->Right);
            else 
                return Root;
        }
        BiTreeNode*_FindMin(BiTreeNode*Root)            //最小的在最左边
        {
            if(!Root)return NULL;
            else if(!Root->Left)
                return Root;
            else
                return _FindMin(Root->Left);
        }
        BiTreeNode*_FindMax(BiTreeNode*Root)            //……
        {
            if(Root)
            {
                while(Root->Right)Root=Root->Right;
            }
            return Root;
        }
        BiTreeNode*_Insert(const ElemType X,BiTreeNode*&Root)
        {
            if(!Root)
            {
                Root=new BiTreeNode(X);
                //cout<<"successful"<<endl;
            }
            else
            {
                if(X<Root->Data)
                    Root->Left=_Insert(X,Root->Left); //换个思路?返回插入后左右结点
                else
                    Root->Right=_Insert(X,Root->Right);
            }
            return Root;
        }
        BiTreeNode*_Delete(const ElemType X,BiTreeNode*&Root)
        {
            BiTreeNode*Tmp;
            if(!Root)return NULL;
            if(X<Root->Data)
                Root->Left=_Delete(X,Root->Left);
            else if(X>Root->Data)
                Root->Right=_Delete(X,Root->Right);
            else                                           //找到待删除元素之后
            {                                               /如果该结点有两个子树
                if(Root->Left&&Root->Right)                 //用左子树最大值,
                {                                           //或右子树最小值,
                    Tmp=_FindMin(Root->Right);              //替换该结点
                    Root->Data=Tmp->Data;                  //并删除左右子树相应结点
                    Root->Right=_Delete(Root->Data,Root->Right); //结点在左树最右
                    /*                                            //或右树最左
                    Tmp=FindMax(Root->Left);                    //不可能有两个孩子
                    Root->Data=Tmp->Data;            //所以下面的else可以删除该结点
                    Root->Left=_Delete(Root->Data,Root->Left);
                    */
                }else{
                    Tmp=Root;
                    if(!Root->Left)Root=Root->Right;  //没有左孩子,用右孩子替换结点
                    else if(!Root->Right)Root=Root->Left;       //……
                    free(Tmp);
                }
            }
            return Root;
        }
    private:
        BiTreeNode*Root;
};
int main()
{
    char a[]="012##3##4##";
    Thread_Tree tree(a,strlen(a));
    tree.PreOrderThreading();
    tree.PreOrder();
    cout<<endl<<"*******************"<<endl;
    Binary_Search_Tree tree1;
    tree1.Insert('a');
    tree1.Insert('b');
    tree1.Insert('e');
    tree1.Insert('d');
    cout<<"max: "<<tree1.FindMax()->Data<<endl;
    cout<<"min: "<<tree1.FindMin()->Data<<endl;
    cout<<"find b: "<<tree1.Find('b')->Data<<endl;
    tree1.Delete('e');
    cout<<"max after delete e: "<<tree1.FindMax()->Data<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37613112/article/details/87769033