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

二叉树是一种有些特殊的数据结构,因为单独一个顶点也算二叉树。那么,我们不妨定义二叉树的结点类,而不是去定义整个二叉树类。下面是二叉树的节点类:

#include <iostream>

using namespace std;

#ifndef TREENODE_H_INCLUDED
#define TREENODE_H_INCLUDED

template <class ElemType>
class TreeNode
{
private:
    TreeNode* lchild;
    TreeNode* rchild;
public:
    ElemType data;
    TreeNode(const ElemType& item,TreeNode* lptr=NULL,TreeNode* rptr=NULL):
    lchild(lptr),rchild(rptr),data(item){ }
    ~TreeNode(){ }
    TreeNode*& LeftChild(){return lchild;}
    TreeNode*& RightChild(){return rchild;}
};

#endif // TREENODE_H_INCLUDED

下面是对二叉树进行的遍历操作,包括先序、中序、后序遍历的递归形式和非递归形式,还包括了按层遍历:

#include <iostream>
#include "TreeNode.h"
#include "../LinkQueue/LinkQueue.h"
#include "../LinkStack/LinkStack.h"

using namespace std;

#ifndef TREESCAN_H_INCLUDED
#define TREESCAN_H_INCLUDED

template <class ElemType>
void PreOrderTraverse(TreeNode<ElemType>* t,void (*Visit)(ElemType &e))
{
    if(t)
    {
        Visit(t->data);
        PreOrderTraverse(t->LeftChild(),Visit);
        PreOrderTraverse(t->RightChild(),Visit);
    }
}
template <class ElemType>
void InOrderTraverse(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
    if(t)
    {
        InOrderTraverse(t->LeftChild(),Visit);
        Visit(t->data);
        InOrderTraverse(t->RightChild(),Visit);
    }
}
template <class ElemType>
void PostOrderTraverse(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
    if(t)
    {
        PostOrderTraverse(t->LeftChild(),Visit);
        PostOrderTraverse(t->RightChild(),Visit);
        Visit(t->data);
    }
}
template <class ElemType>
void LevelTraverse(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
    LinkQueue<TreeNode<ElemType>*> Q;
    TreeNode<ElemType>* p;
    Q.EnQueue(t);
    while(!Q.QueueEmpty())
    {
        Q.DeQueue(p);
        Visit(p->data);
        if(p->LeftChild())
        {
            Q.EnQueue(p->LeftChild());
        }
        if(p->RightChild())
        {
            Q.EnQueue(p->RightChild());
        }
    }
}
template <class ElemType>
void PreOrderTraverse_I(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
    LinkStack<TreeNode<ElemType>*> S;
    TreeNode<ElemType>* p=t;
    while(p||!S.StackEmpty())
    {
        while(p)
        {
            Visit(p->data);
            S.Push(p);
            p=p->LeftChild();
        }
        if(!S.StackEmpty())
        {
            S.Pop(p);
            p=p->RightChild();
        }
    }
}
template <class ElemType>
void InOrderTraverse_I(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
    LinkStack<TreeNode<ElemType>*> S;
    TreeNode<ElemType>* p=t;
    while(p||!S.StackEmpty())
    {
        while(p)
        {
            S.Push(p);
            p=p->LeftChild();
        }
        if(!S.StackEmpty())
        {
            S.Pop(p);
            Visit(p->data);
            p=p->RightChild();
        }
    }
}
template <class ElemType>
struct StackNode
{
    TreeNode<ElemType>* ptr;
    int tag;
};
template <class ElemType>
void PostOrderTraverse_I(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
    StackNode<ElemType> curnode,topnode;
    LinkStack<StackNode<ElemType> > S;
    TreeNode<ElemType>* p=t;
    do
    {
        while(p)
        {
            curnode.ptr=p;
            curnode.tag=0;
            S.Push(curnode);
            p=p->LeftChild();
        }
        S.GetTop(topnode);
        while(!S.StackEmpty()&&topnode.tag==1)
        {
            S.Pop(curnode);
            p=curnode.ptr;
            Visit(p->data);
            S.GetTop(topnode);
        }
        if(!S.StackEmpty())
        {
            S.Pop(topnode);
            topnode.tag=1;
            S.Push(topnode);
            p=topnode.ptr->RightChild();
        }
    } while(!S.StackEmpty());
}

#endif // TREESCAN_H_INCLUDED

下面是一些常用的二叉树操作,包括建立二叉树、求二叉树节点数、求二叉树叶子数、求二叉树深度、销毁二叉树等:

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

using namespace std;

#ifndef BITREE_H_INCLUDED
#define BITREE_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);
    return p;
}
template <class ElemType>
void FreeTreeNode(TreeNode<ElemType>* p)
{
    delete p;
}
template <class ElemType>
int CountLeaf(TreeNode<ElemType>* t)
{
    if(t)
    {
        if(!t->LeftChild()&&!t->RightChild())
        {
            return 1;
        }
        else
        {
            return CountLeaf(t->LeftChild())+CountLeaf(t->RightChild());
        }
    }
    else
    {
        return 0;
    }
}
template <class ElemType>
int CountNode(TreeNode<ElemType>* t)
{
    if(t)
    {
        if(!t->LeftChild()&&!t->RightChild())
        {
            return 1;
        }
        else
        {
            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
    {
        depthleft=Depth(t->LeftChild());
        depthright=Depth(t->RightChild());
        depthval=1+(depthleft>depthright?depthleft:depthright);
    }
    return depthval;
}
template <class ElemType>
TreeNode<ElemType>* CopyTree(TreeNode<ElemType>* t)
{
    TreeNode<ElemType>* newnode,*newlptr,*newrptr;
    if(!t)
    {
        return NULL;
    }
    if(t->LeftChild())
    {
        newlptr=CopyTree(t->LeftChild());
    }
    else
    {
        newlptr=NULL;
    }
    if(t->RightChild())
    {
        newrptr=CopyTree(t->RightChild());
    }
    else
    {
        newrptr=NULL;
    }
    newnode=new TreeNode<ElemType>(t->data,newlptr,newrptr);
    return newnode;
}
template <class ElemType>
void DeleteTree(TreeNode<ElemType>* t)
{
    if(t)
    {
        DeleteTree(t->LeftChild());
        DeleteTree(t->RightChild());
        FreeTreeNode(t);
    }
}
template <class ElemType>
void ClearTree(TreeNode<ElemType>* &t)
{
    DeleteTree(t);
    t=NULL;
}

#endif // BITREE_H_INCLUDED

写二叉树的时候用到了自己之前写的链栈类和链队列类。参考了国外的经典教材《数据结构C++语言描述》。
 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值