您的位置:首页 > 理论基础 > 数据结构算法

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

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

#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++语言描述》。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息