数据结构的知识忘了好多了。今天实现了一下二叉树及相关操作,对二叉树的遍历采用了递归的方法,当然也可以用非递归方法。附上代码:
/*****************************二叉树的建立及相关操作******************************/
//by vipper.zhang 2011.7.8 如果有什么问题或者可以改进的建议,请发邮件vipper.zhang@gmail.com
//O(∩_∩)0
#include "stdafx.h"
#include <iostream>
#include <queue>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}*BiTree;
void InitBiTree(BiTree &T)
{
T=NULL;
}
//创建二叉树,递归建立二叉树
//注意:
//递归思想
BiTree CreateBiTree(BiTree &T)
{
cout<<"input the element of the tree: "<<endl;
char ia;
cin>>ia;
if(ia=='@') { T=NULL; }
else
{
BiTree p=new BiTNode();
p->data =ia;
p->lchild = p->rchild = NULL;
T=p;
CreateBiTree(T->lchild );
CreateBiTree(T->rchild );
}
return T;
}
//打印树的元素,需要遍历,那就递归
void PrintBiTree(BiTree &T)
{
if(T==NULL)
cout<<"over!"<<endl;
else
{
cout<<T->data <<"\t";
PrintBiTree(T->lchild );
PrintBiTree(T->rchild );
}
}
//销毁树 销毁就是销毁了二叉树的内存空间,二叉树不存在
void DestroyBiTree(BiTree &T)
{
if(T!=NULL)
delete T;
}
//清空树 清空了树在内存中的单元还在,只是没有确切的值,但树依然还在
void ClearBiTree(BiTree &T)
{
if(T!=NULL)
{
T->lchild=NULL;
T->rchild=NULL;
T=NULL;
}
}
//树是否为空
bool BiTreeEmpty(BiTree T)
{
if(T)
return true;
else
return false;
}
//二叉树的深度,又是递归求解
int BiTreeDepth(BiTree T)
{
if(T==NULL) return 0;
int dep=0;
int left=1;
int right=1;
BiTree p=T;
left=BiTreeDepth(T->lchild );
right=BiTreeDepth(T->rchild);
dep=1+(left>=right ? left:right);
return dep;
}
//返回二叉树某节点的值
char Value(BiTree T,BiTree e)
{
return e->data ;
}
//给某节点赋新值
void Assign(BiTree T,BiTree &e,char value)
{
e->data =value;
}
//求双亲
BiTree Parent(BiTree T,BiTree e)
{
BiTree tmp;
if(T==e)
return NULL;
else if(T->lchild==e||T->rchild==e)
return T;
else if((tmp=Parent(T->lchild,e))!=NULL)
return tmp;
else
return Parent(T->rchild,e);
}
//结点e的左孩子
BiTree LeftChild(BiTree T,BiTree e)
{
if(e->lchild==NULL)
return NULL;
else
return e->lchild;
}
//结点e的右孩子
BiTree RightChild(BiTree T,BiTree e)
{
if(e->rchild==NULL)
return NULL;
else
return e->rchild;
}
//求结点e的左兄弟
BiTree LeftSibling(BiTree T,BiTree e)
{
BiTree parent=Parent(T,e);
if(e==parent->lchild||parent->lchild ==NULL )
return NULL;
else
return e->lchild ;
}
//求结点e的右兄弟
BiTree RightSibling(BiTree T,BiTree e)
{
BiTree parent=Parent(T,e);
if(e==parent->rchild||parent->rchild ==NULL )
return NULL;
else
return e->rchild ;
}
//根据LR为0或者1,插入c为T中p所指向结点的左或者右子树,p所致结点的原有左或右子树则成为c的右子树
void InsertChild(BiTree &T,BiTree &p,int LR,BiTree &c) //p指向T中某个节点,LR为0或1,非空二叉树c与T不相交且右子树为空
{
if(LR=0)
{
c->rchild =p->lchild;
p->lchild=c;
}
else
c->rchild =p->rchild ;
p->rchild =c;
}
//同上,删除p结点的孩子结点
void DeleteChild(BiTree &T,BiTree &p,int LR)
{
if(LR=0)
p->lchild =NULL;
else if(LR=1)
p->rchild =NULL;
}
//先序遍历,注意递归的位置
void PreOrderTraverse(BiTree T)
{
if(T==NULL)
;
else{
cout<<T->data <<"\t";
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//中序遍历
void InOrderTraverse(BiTree T)
{
if(T!=NULL)
{
InOrderTraverse(T->lchild );
cout<<T->data <<"\t";
InOrderTraverse(T->rchild);
}
}
//后序遍历
void PostOrderTraverse(BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild );
PostOrderTraverse(T->rchild );
cout<<T->data <<"\t";
}
}
//层序遍历
void LevelOrderTraverse(BiTree T)
{
queue<BiTree> que;
BiTree p=T;
que.push(T);
while(!que.empty() )
{
p=que.front();
cout<<p->data <<"\t";
que.pop();
if(p->lchild!=NULL)
que.push(p->lchild );
if(p->rchild!=NULL)
que.push(p->rchild );
}
}
//计算叶子结点总数,两个参数
int CountLeaf(BiTree T,int &count)
{
if(T!=NULL)
{
if((T->lchild==NULL)&&(T->rchild==NULL))
count++;
CountLeaf(T->lchild,count );
CountLeaf(T->rchild ,count);
}
return count;
}
int _tmain(int argc, _TCHAR* argv[])
{
BiTree bt;
//创建二叉树
CreateBiTree(bt); //创建二叉树
//打印树各节点元素
PrintBiTree(bt);
//深度
int depth=BiTreeDepth(bt);
cout<<"the depth is "<<depth<<endl;;
//四种遍历
PreOrderTraverse(bt);cout<<endl;
InOrderTraverse(bt); cout<<endl;
PostOrderTraverse(bt);cout<<endl;
LevelOrderTraverse(bt);cout<<endl;
//计算叶子结点总数
int count=0;
cout<<"the total leaves are: "<<CountLeaf(bt,count)<<endl;
//两树合并
BiTree bt1;
CreateBiTree(bt1);
InsertChild(bt,bt->lchild,0,bt1);
PreOrderTraverse(bt);cout<<endl;
//删除结点,删除的是根节点的右子树
DeleteChild(bt,bt,1);
PreOrderTraverse(bt);cout<<endl;
system("pause");
return 0;
}
测试用例:
1:输入1 2 @ 3 @ @ 4 @ @来创建树
2:两树合并时,另一个树的输入:5 6@ 7 @ @ @