您的位置:首页 > 编程语言 > C语言/C++

C++ 二叉树的实现以及指针使用注意事项

2010-12-08 15:05 736 查看
关于二叉树可以参考wiki:http://zh.wikipedia.org/zh-cn/%E4%BA%8C%E5%8F%89%E6%A0%91/*********************************************************
*Description:参数传递:C++二叉树的实现以及指针使用注意事项
*Author:charley
*DateTime:2010-12-811:00
*CompileEnvironment:win7+vs2008
***********************************************************/

#include<iostream>
usingnamespacestd;

//*************************************************************************************
//二叉树结点类的定义
template<classT>//模版结构体
structTreeNode
{
Tdata;//节点的内容
TreeNode<T>*Lchild,*Rchild;//节点的左子树和右子树

//可选择参数的默认构造函数
/*TreeNode(TnodeValue=T(),TreeNode<T>*leftNode=NULL,TreeNode<T>*rightNode=NULL)
:data(nodeValue),Lchild(leftNode),Rchild(rightNode){}*/
};

//**************************************************************************************
//二叉树的建立
template<classT>//模版方法
voidcreateBinaryTree(TreeNode<T>*&root)//传递指针的引用
{
TreeNode<T>*p=root;
TnodeValue;
cin>>nodeValue;
if(nodeValue==-1)
{
root=NULL;
}
else
{
root=newTreeNode<T>();//构造一个节点
root->data=nodeValue;
createBinaryTree(root->Lchild);//递归构造左子树
createBinaryTree(root->Rchild);//递归构造右子树
}
}

//************************************************************************************
//二叉树的先序遍历
template<classT>
voidpreOrder(TreeNode<T>*&p)//传递指针的引用
{
if(p)
{
cout<<p->data<<"";
preOrder(p->Lchild);
preOrder(p->Rchild);
}
}

//**************************************************************************************
//二叉树的中序遍历
template<classT>
voidinOrder(TreeNode<T>*&p)//传递指针的引用
{

if(p)
{
inOrder(p->Lchild);
cout<<p->data<<"";
inOrder(p->Rchild);
}
}

//**************************************************************************************
//二叉树的后序遍历
template<classT>
voidpostOrder(TreeNode<T>*&p)//传递指针的引用
{
if(p)
{
postOrder(p->Lchild);
postOrder(p->Rchild);
cout<<p->data<<"";
}
}

//*************************************************************************************
//统计二叉树中结点的个数
template<classT>
intcountNode(TreeNode<T>*&p)//传递指针的引用
{
if(p==NULL)return0;
return1+countNode(p->Lchild)+countNode(p->Rchild);
}

//***********************************************************************************
//求二叉树的深度
template<classT>
intdepth(TreeNode<T>*&p)//传递指针的引用
{
if(p==NULL)
return-1;
inth1=depth(p->Lchild);
inth2=depth(p->Rchild);
if(h1>h2)return(h1+1);
returnh2+1;
}

//***********************************************************************************
//二叉树的消毁操作
//容易混淆的错误声明:voiddestroy(TreeNode<T>*p)这种声明会创建一个局部的临时对象来保存传递的指针
//虽然2个指针都执行同一块堆空间,delete局部指针也会删除二叉树结构所占用的堆内存
//但是全局传递的那个指针将会是垃圾指针,会产生不可预料的错误
//voiddestroy(TreeNode<T>*&p)此函数的参数为全局指针的一个别名,代表全局指针rootNode本身
// 这样p=NULL;能达到置空指针的左右
//可选的方案是在调用完destroy方法之后,在主函数中执行rootNode=NULL操作
template<classT>
voiddestroy(TreeNode<T>*&p)//传递指针的引用,消毁函数,用来消毁二叉树中的各个结点
{
if(p)
{
//错误return之后没有执行deletep
//returndestroy(p->Lchild);
//returndestroy(p->Rchild);

destroy(p->Lchild);
destroy(p->Rchild);

//delete只能释放由用户通过new方式在堆中申请的内存,
//是通过变量声明的方式由系统所声明的栈内存不能使用delete删除

//delete和free函数一样,不修改它参数对应指针指向的内容,也不修改指针本身,
//只是在堆内存管理结构中将指针指向的内容标记为可被重新分配
deletep;

//堆上内存释放栈上指针并不销毁
//此时p指向的地址未知,此时执行*p=?操作会导致不可预料的错误
//但是可以重新赋值p=&x;
//最好delete之后把P置空
p=NULL;

}
}

//********************************************************************************
//主函数的设计
intmain()
{
TreeNode<int>*rootNode=NULL;
intchoiced=0;
while(true)
{
system("cls");//清屏
cout<<"\n\n\n---主界面---\n\n\n";
cout<<"1、创建二叉树2、先序遍历二叉树\n";
cout<<"3、中序遍历二叉树4、后序遍历二叉树\n";
cout<<"5、统计结点总数6、查看树深度\n";
cout<<"7、消毁二叉树0、退出\n\n";
cout<<"请选择操作:";
cin>>choiced;
if(choiced==0)
return0;
elseif(choiced==1)
{
system("cls");
cout<<"请输入每个结点,回车确认,并以-1结束:\n";
createBinaryTree(rootNode);
}
elseif(choiced==2)
{
system("cls");
cout<<"先序遍历二叉树结果:\n";
preOrder(rootNode);
cout<<endl;
system("pause");//暂停屏幕
}
elseif(choiced==3)
{
system("cls");
cout<<"中序遍历二叉树结果:\n";
inOrder(rootNode);
cout<<endl;
system("pause");
}
elseif(choiced==4)
{
system("cls");
cout<<"后序遍历二叉树结果:\n";
postOrder(rootNode);
cout<<endl;
system("pause");
}
elseif(choiced==5)
{
system("cls");
intcount=countNode(rootNode);
cout<<"二叉树中结点总数为"<<count<<endl;
system("pause");
}
elseif(choiced==6)
{
system("cls");
intdep=depth(rootNode);
cout<<"此二叉树的深度为"<<dep<<endl;
system("pause");
}
elseif(choiced==7)
{
system("cls");
cout<<"二叉树已被消毁!\n";
destroy(rootNode);
cout<<endl;
system("pause");
}
else
{
system("cls");
cout<<"\n\n\n\n\n\t错误选择!\n";
}

}
}

假如本程序要生成的二叉树如下:





则创建二叉树输入的顺序为:8751–1–1–14–1–163–1–12–1-1

除了-1节点之外的就是实际创建的二叉树

-1不是实际的节点、输入-1仅表示子节点为空返回继续创建其他节点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: