猫咪的晴天

记录,总结,提高

简单数据结构的实现之线索二叉树

 线索二叉树,我写过的比较恶心的数据结构之一。我一直认为线索化应该是对二叉树的一个操作。可是,线索二叉树与普通的二叉树却实在大有不同。算了,不说了,上代码!

#include <iostream>

using namespace std;

#ifndef TREENODE_H_INCLUDED
#define TREENODE_H_INCLUDED

enum PointerTag
{
    Link,
    Thread
};
template <class ElemType>
class TreeNode
{
private:
    TreeNode* lchild;
    TreeNode* rchild;
    TreeNode* parent;
    PointerTag ltag;
    PointerTag rtag;
public:
    ElemType data;
    TreeNode(const ElemType& item,TreeNode* lptr=NULL,TreeNode* rptr=NULL,PointerTag lt=Link,PointerTag rt=Link,TreeNode* par=NULL):
    lchild(lptr),rchild(rptr),parent(par),ltag(lt),rtag(rt),data(item){ }
    ~TreeNode(){ }
    TreeNode* LeftChild(){return lchild;}
    TreeNode* RightChild(){return rchild;}
    void SetLeftChild(TreeNode* chd){lchild=chd;}
    void SetRightChild(TreeNode* chd){rchild=chd;}
    void SetParent(TreeNode* par){parent=par;}
    TreeNode* Parent(){return parent;}
    PointerTag LeftTag(){return ltag;}
    PointerTag RightTag(){return rtag;}
    void SetLeftTag(PointerTag tag){ltag=tag;}
    void SetRightTag(PointerTag tag){rtag=tag;}
};

#endif // TREENODE_H_INCLUDED
#include <iostream>
#include <list>
#include "treenode.h"

using namespace std;

#ifndef TREELIB_H_INCLUDED
#define TREELIB_H_INCLUDED

template <class ElemType>
TreeNode<ElemType>* GetTreeNode(ElemType item,TreeNode<ElemType>* lptr,TreeNode<ElemType>* rptr)
{
    TreeNode<ElemType>* p=new TreeNode<ElemType>(item,lptr,rptr,Link,Link);
    if(lptr)
    {
        lptr->SetParent(p);
    }
    if(rptr)
    {
        rptr->SetParent(p);
    }
    return p;
}
template <class ElemType>
void FreeNode(TreeNode<ElemType>* t)
{
    delete t;
}
template <class ElemType>
void InThreading(TreeNode<ElemType> * t,TreeNode<ElemType>* &pre)
{
    if(t)
    {
        InThreading(t->LeftChild(),pre);
        if(!t->LeftChild())
        {
            t->SetLeftTag(Thread);
            t->SetLeftChild(pre);
        }
        if(!pre->RightChild())
        {
            pre->SetRightTag(Thread);
            pre->SetRightChild(t);
        }
        pre=t;
        InThreading(t->RightChild(),pre);
    }
}
template <class ElemType>
bool InorderThreading(TreeNode<ElemType> *t,TreeNode<ElemType>* &thrt)
{
    thrt=new TreeNode<ElemType>(' ');
    TreeNode<ElemType>* pre;
    if(!thrt)
    {
        return false;
    }
    thrt->SetLeftTag(Link);
    thrt->SetRightTag(Thread);
    thrt->SetRightChild(thrt);
    if(!t)
    {
        thrt->SetLeftChild(thrt);
    }
    else
    {
        thrt->SetLeftChild(t);
        pre=thrt;
        InThreading(t,pre);
        pre->SetRightTag(Thread);
        pre->SetRightChild(thrt);
        thrt->SetRightChild(pre);
    }
    return true;
}
template <class ElemType>
void PreThreading(TreeNode<ElemType>* t,TreeNode<ElemType>* &pre)
{
    if(t)
    {
        if(!t->LeftChild())
        {
            t->SetLeftTag(Thread);
            t->SetLeftChild(pre);
        }
        if(!pre->RightChild())
        {
            pre->SetRightTag(Thread);
            pre->SetRightChild(t);
        }
        pre=t;
        if(t->LeftTag()==Link)
        {
            PreThreading(t->LeftChild(),pre);
        }
        if(t->RightTag()==Link)
        {
            PreThreading(t->RightChild(),pre);
        }
    }
}
template <class ElemType>
bool PreorderThreading(TreeNode<ElemType> *t,TreeNode<ElemType>* &thrt)
{
    thrt=new TreeNode<ElemType>(' ');
    TreeNode<ElemType>* pre;
    if(!thrt)
    {
        return false;
    }
    thrt->SetLeftTag(Link);
    thrt->SetRightTag(Thread);
    thrt->SetRightChild(thrt);
    if(!t)
    {
        thrt->SetLeftChild(thrt);
    }
    else
    {
        thrt->SetLeftChild(t);
        pre=thrt;
        PreThreading(t,pre);
        pre->SetRightTag(Thread);
        pre->SetRightChild(thrt);
        thrt->SetRightChild(pre);
    }
    return true;
}
template <class ElemType>
void PostThreading(TreeNode<ElemType> *t,TreeNode<ElemType>* &pre)
{
    if(t)
    {
        PostThreading(t->LeftChild(),pre);
        PostThreading(t->RightChild(),pre);
        if(!t->LeftChild())
        {
            t->SetLeftTag(Thread);
            t->SetLeftChild(pre);
        }
        if(!pre->RightChild())
        {
            pre->SetRightTag(Thread);
            pre->SetRightChild(t);
        }
        pre=t;
    }
}
template <class ElemType>
bool PostorderThreading(TreeNode<ElemType> *t,TreeNode<ElemType>* &thrt)
{
    thrt=new TreeNode<ElemType>(' ');
    TreeNode<ElemType>* pre;
    if(!thrt)
    {
        return false;
    }
    thrt->SetLeftTag(Link);
    thrt->SetRightTag(Thread);
    thrt->SetRightChild(thrt);
    if(!t)
    {
        thrt->SetLeftChild(thrt);
    }
    else
    {
        thrt->SetLeftChild(t);
        pre=thrt;
        PostThreading(t,pre);
        thrt->SetRightChild(pre);
    }
    return true;
}
template <class ElemType>
int CountLeaf(TreeNode<ElemType>* t)
{
    if(t)
    {
        if(t->LeftTag()==Thread&&t->RightTag()==Thread)
        {
            return 1;
        }
        if(t->LeftTag()==Link&&t->RightTag()==Thread)
        {
            return CountLeaf(t->LeftChild());
        }
        if(t->LeftTag()==Thread&&t->RightTag()==Link)
        {
            return CountLeaf(t->RightChild());
        }
        return CountLeaf(t->LeftChild())+CountLeaf(t->RightChild());
    }
    else
    {
        return 0;
    }
}
template <class ElemType>
int CountNode(TreeNode<ElemType>* t)
{
    if(t)
    {
        if(t->LeftTag()==Thread&&t->RightTag()==Thread)
        {
            return 1;
        }
        if(t->LeftTag()==Link&&t->RightTag()==Thread)
        {
            return CountNode(t->LeftChild())+1;
        }
        if(t->LeftTag()==Thread&&t->RightTag()==Link)
        {
            return CountNode(t->RightChild())+1;
        }
        return CountNode(t->LeftChild())+CountNode(t->RightChild())+1;
    }
    else
    {
        return 0;
    }
}
template <class ElemType>
int Depth(TreeNode<ElemType>* t)
{
    int depthleft,depthright,depthval;
    if(!t)
    {
        depthval=0;
    }
    else
    {
        if(t->LeftTag()==Link&&t->RightTag()==Link)
        {
            depthleft=Depth(t->LeftChild());
            depthright=Depth(t->RightChild());
        }
        else if(t->LeftTag()==Link&&t->RightTag()==Thread)
        {
            depthleft=Depth(t->LeftChild());
            depthright=0;
        }
        else if(t->LeftTag()==Thread&&t->RightTag()==Link)
        {
            depthleft=0;
            depthright=Depth(t->RightChild());
        }
        else
        {
            depthleft=depthright=0;
        }
        depthval=1+(depthleft>depthright?depthleft:depthright);
    }
    return depthval;
}
template <class ElemType>
void DeleteTree(TreeNode<ElemType>* t)
{
    if(t)
    {
        if(t->LeftTag()==Link)
        {
            DeleteTree(t->LeftChild());
        }
        if(t->RightTag()==Link)
        {
            DeleteTree(t->RightChild());
        }
        FreeNode(t);
    }
}
template <class ElemType>
void ClearTree(TreeNode<ElemType>* &t)
{
    DeleteTree(t);
    t=NULL;
}

#endif // TREELIB_H_INCLUDED


 

#include <iostream>
#include "treenode.h"

using namespace std;

#ifndef TREESCAN_H_INCLUDED
#define TREESCAN_H_INCLUDED

template <class ElemType>
void PreorderTraverse(TreeNode<ElemType>* thrt,void (*Visit)(ElemType& e))
{
    TreeNode<ElemType>* p=thrt->LeftChild();
    while(p!=thrt)
    {
        Visit(p->data);
        if(p->LeftTag()==Link)
        {
            p=p->LeftChild();
        }
        else
        {
            p=p->RightChild();
        }
    }
}
template <class ElemType>
void InorderTraverse(TreeNode<ElemType>* thrt,void (*Visit)(ElemType& e))
{
    TreeNode<ElemType>* p=thrt->LeftChild();
    while(p!=thrt)
    {
        while(p->LeftTag()==Link)
        {
            p=p->LeftChild();
        }
        Visit(p->data);
        while(p->RightTag()==Thread&&p->RightChild()!=thrt)
        {
            p=p->RightChild();
            Visit(p->data);
        }
        p=p->RightChild();
    }
}
template <class ElemType>
void PostorderTraverse(TreeNode<ElemType>* thrt,void (*Visit)(ElemType& e))
{
    TreeNode<ElemType>* p=thrt->LeftChild();
    TreeNode<ElemType>* par;
    while(p->LeftTag()==Link||p->RightTag()==Link)
    {
        while(p->LeftTag()==Link)
        {
            p=p->LeftChild();
        }
        if(p->RightTag()==Link)
        {
            p=p->RightChild();
        }
    }
    while(p!=thrt)
    {
        Visit(p->data);
        if(!p->Parent())
        {
            break;
        }
        par=p->Parent();
        if(p==par->RightChild()||par->RightTag()==Thread)
        {
            p=par;
        }
        else
        {
            par=par->RightChild();
            while(par->LeftTag()==Link||par->RightTag()==Link)
            {
                while(par->LeftTag()==Link)
                {
                    par=par->LeftChild();
                }
                if(par->RightTag()==Link)
                {
                    par=par->RightChild();
                }
            }
            p=par;
        }
    }
}

#endif // TREESCAN_H_INCLUDED


#include <iostream>
#include <iomanip>
#include "treenode.h"
#include "treelib.h"
#include "treescan.h"

using namespace std;

void Visit(char& x)
{
    cout<<x;
}
int main()
{
    TreeNode<char> *root1,*root2,*root3;
    TreeNode<char>* thrt;
    TreeNode<char> *a,*b,*c,*d,*e,*f,*g,*h,*i;

    d = GetTreeNode('D',(TreeNode<char> *)NULL,(TreeNode<char> *)NULL);
    e = GetTreeNode('E',(TreeNode<char> *)NULL,(TreeNode<char> *)NULL);
    b = GetTreeNode('B',(TreeNode<char> *)NULL, d);
    c = GetTreeNode('C',e, (TreeNode<char> *)NULL);
    a = GetTreeNode('A',b, c);
    root1 = a;
    InorderThreading(root1,thrt);
    cout<<"after executing the function of InorderThreading, "<<endl;
    cout<<"the number of leaves is "<<CountLeaf(root1)<<endl;
    cout<<"the number of nodes is "<<CountNode(root1)<<endl;
    cout<<"the depth of this binary tree is "<<Depth(root1)<<endl;
    cout<<"InorderTraverse result: "<<endl;
    InorderTraverse(thrt,Visit);
    cout<<endl;
    FreeNode(thrt);
    ClearTree(root1);
    cout<<"after executing the function of ClearTree, "<<endl;
    cout<<"the number of leaves is "<<CountLeaf(root1)<<endl;
    cout<<"the number of nodes is "<<CountNode(root1)<<endl;
    cout<<"the depth of this binary tree is "<<Depth(root1)<<endl;

    g = GetTreeNode('G',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    h = GetTreeNode('H',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    i = GetTreeNode('I',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    d = GetTreeNode('D',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    e = GetTreeNode('E',g, (TreeNode<char> *)NULL);
    f = GetTreeNode('F',h, i);
    b = GetTreeNode('B',d, e);
    c = GetTreeNode('C',(TreeNode<char> *)NULL, f);
    a = GetTreeNode('A',b, c);
    root2=a;
    PreorderThreading(root2,thrt);
    cout<<"after executing the function of PreorderThreading, "<<endl;
    cout<<"the number of leaves is "<<CountLeaf(root2)<<endl;
    cout<<"the number of nodes is "<<CountNode(root2)<<endl;
    cout<<"the depth of this binary tree is "<<Depth(root2)<<endl;
    cout<<"PreorderTraverse result: "<<endl;
    PreorderTraverse(thrt,Visit);
    cout<<endl;
    FreeNode(thrt);
    ClearTree(root2);
    cout<<"after executing the function of ClearTree, "<<endl;
    cout<<"the number of leaves is "<<CountLeaf(root2)<<endl;
    cout<<"the number of nodes is "<<CountNode(root2)<<endl;
    cout<<"the depth of this binary tree is "<<Depth(root2)<<endl;

    g = GetTreeNode('G',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    h = GetTreeNode('H',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    i = GetTreeNode('I',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    d = GetTreeNode('D',(TreeNode<char> *)NULL, g);
    e = GetTreeNode('E',h, i);
    f = GetTreeNode('F',(TreeNode<char>*)NULL,(TreeNode<char>*)NULL);
    b = GetTreeNode('B',d, (TreeNode<char> *)NULL);
    c = GetTreeNode('C',e, f);
    a = GetTreeNode('A',b, c);
    root3=a;
    PostorderThreading(root3,thrt);
    cout<<"after executing the function of PostorderThreading, "<<endl;
    cout<<"the number of leaves is "<<CountLeaf(root3)<<endl;
    cout<<"the number of nodes is "<<CountNode(root3)<<endl;
    cout<<"the depth of this binary tree is "<<Depth(root3)<<endl;
    cout<<"PostorderTraverse result: "<<endl;
    PostorderTraverse(thrt,Visit);
    cout<<endl;
    FreeNode(thrt);
    ClearTree(root3);
    cout<<"after executing the function of ClearTree, "<<endl;
    cout<<"the number of leaves is "<<CountLeaf(root3)<<endl;
    cout<<"the number of nodes is "<<CountNode(root3)<<endl;
    cout<<"the depth of this binary tree is "<<Depth(root3)<<endl;
    return 0;
}


treenode.h用于定义线索二叉树的节点类,treelib.h用于实现一些线索二叉树的常用操作,比如说线索化等等,treescan.h包括了线索二叉树的先序、中序和后序遍历。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qtyl1988/article/details/6882692
想对作者说点什么? 我来说一句

线索二叉树的插入,删除

2010年05月26日 997KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭