C++二叉树的操作

转至:http://www.cnblogs.com/charley_yang/archive/2010/12/08/1900256.html 

关于二叉树可以参考wiki:http://zh.wikipedia.org/zh-cn/%E4%BA%8C%E5%8F%89%E6%A0%91

 
001/*********************************************************
002* Description:参数传递:C++ 二叉树的实现以及指针使用注意事项
003* Author:charley
004* DateTime:2010-12-8 11:00
005* Compile Environment:win7+vs2008
006***********************************************************/
007  
008#include <iostream>
009using namespace std;
010  
011//*************************************************************************************
012//二叉树结点类的定义
013template<class T>                  //模版结构体
014struct TreeNode
015{
016    T data;                       //节点的内容
017    TreeNode <T> *Lchild,*Rchild; //节点的左子树和右子树
018  
019    //可选择参数的默认构造函数
020    /*TreeNode(T nodeValue = T(),TreeNode<T> *leftNode = NULL,TreeNode<T> *rightNode = NULL )
021        :data(nodeValue),Lchild(leftNode),Rchild(rightNode){} */      
022};
023  
024//**************************************************************************************
025//二叉树的建立
026template <class T> //模版方法
027void createBinaryTree(TreeNode<T> *&root )  //传递指针的引用
028{
029    TreeNode<T>* p = root;
030    T nodeValue ;
031    cin>>nodeValue;
032    if(nodeValue==-1)
033    {
034        root=NULL;
035    }
036    else
037    {
038        root=new TreeNode<T>();            //构造一个节点
039        root->data = nodeValue;
040        createBinaryTree(root->Lchild);    //递归构造左子树
041        createBinaryTree(root->Rchild);    //递归构造右子树
042    }
043}
044  
045//************************************************************************************
046//二叉树的先序遍历
047template <class T>
048void preOrder( TreeNode<T> * & p) //传递指针的引用
049{
050    if(p)
051    {
052        cout<<p->data<<" ";
053        preOrder(p->Lchild);
054        preOrder(p->Rchild);
055    }
056}
057  
058//**************************************************************************************
059//二叉树的中序遍历
060template <class T>
061void inOrder(TreeNode<T> * & p) //传递指针的引用
062{
063      
064    if(p)
065    {
066        inOrder(p->Lchild);
067        cout<<p->data<<" ";
068        inOrder(p->Rchild);
069    }
070}
071  
072//**************************************************************************************
073//二叉树的后序遍历
074template <class T>
075void postOrder(TreeNode<T> *& p) //传递指针的引用
076{
077    if(p)
078    {
079        postOrder(p->Lchild);
080        postOrder(p->Rchild);
081        cout<<p->data<<" ";
082    }
083}
084  
085//*************************************************************************************
086//统计二叉树中结点的个数
087template<class T>
088int countNode(TreeNode<T> * & p) //传递指针的引用
089{
090    if(p == NULL) return 0;
091    return 1+countNode(p->Lchild)+countNode(p->Rchild);
092}
093  
094//***********************************************************************************
095//求二叉树的深度
096template<class T>
097int depth(TreeNode<T> *& p) //传递指针的引用
098{
099    if(p == NULL)
100        return -1;
101    int h1 = depth(p->Lchild);
102    int h2 = depth(p->Rchild);
103    if(h1>h2)return (h1+1);
104    return h2+1;
105}
106  
107//***********************************************************************************
108//二叉树的消毁操作
109//容易混淆的错误声明:void destroy(TreeNode<T>* p) 这种声明会创建一个局部的临时对象来保存传递的指针
110//虽然2个指针都执行同一块堆空间,delete局部指针 也会删除二叉树结构所占用的堆内存
111//但是全局传递的那个指针将会是垃圾指针,会产生不可预料的错误
112//void destroy(TreeNode<T> *& p) 此函数的参数为全局指针的一个别名,代表全局指针rootNode本身
113//  这样p = NULL;能达到置空指针的左右
114//可选的方案是在调用完destroy方法之后,在主函数中执行rootNode = NULL操作
115template<class T>
116void destroy(TreeNode<T> *& p)  //传递指针的引用,消毁函数,用来消毁二叉树中的各个结点
117{
118    if(p)
119    {
120        //错误 return之后 没有执行delete p
121        //return destroy(p->Lchild);
122        //return destroy(p->Rchild);
123  
124        destroy(p->Lchild);
125        destroy(p->Rchild);
126  
127        //delete只能释放由用户通过new方式在堆中申请的内存,
128        //是通过变量声明的方式由系统所声明的栈内存不能使用delete删除
129  
130        //delete和free函数一样,不修改它参数对应指针指向的内容,也不修改指针本身,
131        //只是在堆内存管理结构中将指针指向的内容标记为可被重新分配
132        delete p;
133  
134        //堆上内存释放 栈上指针并不销毁
135        //此时p指向的地址未知,此时执行*p = ? 操作会导致不可预料的错误
136        //但是可以重新赋值p = &x;
137        //最好delete之后把P置空
138        p = NULL;
139  
140    }
141}
142  
143//********************************************************************************
144//主函数的设计 
145int main ()
146{
147    TreeNode<int> * rootNode = NULL;
148    int choiced = 0;
149    while(true)
150    {
151        system("cls"); //清屏
152        cout<<"\n\n\n                              ---主界面---\n\n\n";
153        cout<<"                     1、创建二叉树                2、先序遍历二叉树\n";
154        cout<<"                     3、中序遍历二叉树            4、后序遍历二叉树\n";
155        cout<<"                     5、统计结点总数              6、查看树深度    \n";
156        cout<<"                     7、消毁二叉树                0、退出\n\n";
157        cout<<"             请选择操作:";
158        cin>>choiced;
159        if(choiced == 0)
160            return 0;
161        else if(choiced == 1)
162        {
163            system("cls");
164            cout<<"请输入每个结点,回车确认,并以-1结束:\n";
165            createBinaryTree(rootNode );
166        }
167        else if(choiced == 2)
168        {
169            system("cls");
170            cout<<"先序遍历二叉树结果:\n";
171            preOrder(rootNode);
172            cout<<endl;
173            system("pause"); //暂停屏幕
174        }
175        else if(choiced == 3)
176        {
177            system("cls");
178            cout<<"中序遍历二叉树结果:\n";
179            inOrder(rootNode);
180            cout<<endl;
181            system("pause");
182        }
183        else if(choiced == 4)
184        {
185            system("cls");
186            cout<<"后序遍历二叉树结果:\n";
187            postOrder(rootNode);
188            cout<<endl;
189            system("pause");
190        }
191        else if(choiced == 5)
192        {
193            system("cls");
194            int count = countNode(rootNode);
195            cout<<"二叉树中结点总数为"<<count<<endl;
196            system("pause");
197        }
198        else if(choiced == 6)
199        {
200            system("cls");
201            int dep = depth(rootNode);
202            cout<<"此二叉树的深度为"<<dep<<endl;
203            system("pause");
204        }
205        else if(choiced == 7)
206        {
207            system("cls");
208            cout<<"二叉树已被消毁!\n";
209            destroy(rootNode);
210            cout<<endl;
211            system("pause");
212        }
213        else 
214        {
215            system("cls");
216            cout<<"\n\n\n\n\n\t错误选择!\n";
217        }
218          
219    }
220}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值