实验三 二叉树的物理实现(二叉链表)

  • 说明
  • 基于链表实现的子结点表示法
  • 参考资料

一、说明:

1、关于二叉链表,(百度百科上的自相矛盾了,引用日期:2018-11-8),也没找着一个确切的说法,有说两个指针一个指向左孩子一个右孩子的,也有说是两个指针一个指向左孩子一个指向兄弟的。在本文中指的是前者(一个指向左孩子,一个指向右孩子);

2、部分说明参考上一篇https://blog.csdn.net/qq_40889820/article/details/83795341

3、以下代码仅供参考。

 

二、基于链表实现的子结点表示法

1、BinNode.h

#include<iostream>
using namespace std;
#ifndef _BinNode
#define _BinNode
namespace wangzhe
{
	template<typename E>
	class BinNode
	{
		private: 
		    E it;
		    BinNode* lc;
		    BinNode* rc;
                public:
        	        BinNode()
        	        {
        		        lc=rc=NULL;
			}
			BinNode(E e,BinNode* l,BinNode* r)
			{
				it=e;lc=l;rc=r;
			}
		        E& element()
		        {
		    	        return it;
			}
		        void setElement(const E& e)
		        {
		    	        it=e;
			}
		        BinNode* left() const
		        {
		    	        return lc;
			}
	    	        void setLeft(BinNode* b)
	    	        {
	    		        lc=b;
			}
	    	        BinNode* right() const
	    	        {
	    		        return rc;
			}
	    	        void setRight(BinNode* b)
	    	        {
	    		        rc=b;
			}
	    	        bool isLeaf()
	    	        {
	    		        return (lc==NULL)&&(rc==NULL);
			}
	};
}
#endif

2、BinTree.h

#include<iostream>
using namespace std;
#include"BinNode.h"
#ifndef _BinTree
#define _BinTree
namespace wangzhe
{
	template<typename E>
	class BinTree
	{
		private:
		        BinNode<E>* root;//根结点 
		public:
			BinTree();//构造函数 
			~BinTree();//析构函数
			BinNode<E>* createBinTree();//前序遍历输入一棵二叉树 
                        void clear(BinNode<E>* r);//销毁一颗二叉树 
			BinNode<E>* Root();//返回根节点
			void setRoot(BinNode<E>* r);//设置根节点 
			bool isEmpty(BinNode<E>* r);//判断二叉树是否为空 
			void preorder(BinNode<E>* r);//前序遍历
			void inorder(BinNode<E>* r);//中序遍历
			void postorder(BinNode<E>* r);//后序遍历
			void levelorder(BinNode<E>* r);//层次遍历
			int BinTreeDepth(BinNode<E>* r);//二叉树深度
			int count(BinNode<E>* r);//二叉树结点数 
			
	};
}
#endif

3、BinTree.cpp

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#include"BinTree.h"
namespace wangzhe
{
	template<typename E>
	BinTree<E>::BinTree()
	{
		root=NULL;
	}
	
	template<typename E>
	BinTree<E>::~BinTree()
	{
		clear(root);
	}
	
	template<typename E>
        BinNode<E>* BinTree<E>::createBinTree()
        {
	    E ele;
	    cin>>ele;
	    BinNode<E>* rt;
	    if(ele=='#') rt=NULL;
	    else 
	    {
		    rt=new BinNode<E>;
		    rt->setElement(ele);
		    rt->setLeft(createBinTree());
		    rt->setRight(createBinTree());
	    }
	    return rt;//返回根结点 
        }
    
	template<typename E>
	void BinTree<E>::clear(BinNode<E>* r)
	{
		if(r==NULL) return;//空树,直接返回
		//只有一个结点 
		if(r->left()==NULL&&r->right()==NULL)
		{
			delete r;
			r=NULL;
			return;
		}
		//大于一个结点,递归销毁左子树与右子树 
		clear(r->left());
		clear(r->right());
		delete r;
		r=NULL;
	}
	
	template<typename E>
	BinNode<E>* BinTree<E>::Root()
	{
		return root;
	}
	
	template<typename E>
	void BinTree<E>::setRoot(BinNode<E>* r)
	{
		root=r;
	}
	
	template<typename E>
	bool BinTree<E>::isEmpty(BinNode<E>* r)
	{
		return root==NULL;
	}
	
	template<typename E>
	void BinTree<E>::preorder(BinNode<E>* r)
	{
		if(r==NULL) return;	
		cout<<r->element() <<' ';
		preorder(r->left());
		preorder(r->right());
	}
	
	template<typename E>
	void BinTree<E>::inorder(BinNode<E>* r)
	{
		if(r==NULL) return;
		inorder(r->left());
		cout<<r->element()<<' ';
		inorder(r->right());
	}
	
	template<typename E>
	void BinTree<E>::postorder(BinNode<E>* r)
	{
		if(r==NULL) return;
		postorder(r->left());
		postorder(r->right());
		cout<<r->element()<<' ';
	}
	
	template<typename E>
	void BinTree<E>::levelorder(BinNode<E>* r)
	{
		queue<BinNode<E>*> q;
		if(r) q.push(r);
		BinNode<E>* temp;
		while(!q.empty())
		{
			temp=q.front();
			q.pop();
			cout<<temp->element()<<' ';
			if(temp->left()) q.push(temp->left());
			if(temp->right()) q.push(temp->right());
		}
	}
	
	template<typename E>
	int BinTree<E>::BinTreeDepth(BinNode<E>* r)
	{
		if(r==NULL) return 0;
		else return max(BinTreeDepth(r->left()),BinTreeDepth(r->right()))+1;
	}
	
	template<typename E>
	int BinTree<E>::count(BinNode<E>* r)
	{
		if(r==NULL) return 0;
		else return 1+count(r->right())+count(r->left());
	}
	
}

4、main.cpp

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#include"BinTree.h"
#include"BinTree.cpp"
using namespace wangzhe;//ABD##E##CG##H##
int main(int argc, char** argv) 
{
	for(int i=1;i<=50;i++) cout<<'*';
        cout<<"\n实验三:二叉树的物理实现(二叉链表实现)\n";
	for(int i=1;i<=50;i++) cout<<'*';
	cout<<endl;
	BinTree<char> tree;
	BinNode<char>* rt;
	cout<<"请以前序遍历的顺序输入一棵树(结点元素类型为字符型),空节点以#代替。"<<endl;
	cout<<"例如:AB#D##CE##F##"<<endl;
	rt=tree.createBinTree() ;
	tree.setRoot(rt); 
	cout<<"这棵树是否是空树?\n";
	if(tree.isEmpty(rt)) cout<<"是,结束操作\n";
	else 
	{
	    cout<<"不是,继续以下操作\n";	
	    cout<<"这棵二叉树前序遍历的结果为:\n" ; 
	    tree.preorder(rt); cout<<endl;
	    cout<<"这棵二叉树中序遍历的结果为:\n" ; 
	    tree.inorder(rt);cout<<endl;  
	    cout<<"这棵二叉树后序遍历的结果为:\n" ; 
	    tree.postorder(rt);cout<<endl;
	    cout<<"这棵二叉树层次遍历的结果为:\n" ;
	    tree.levelorder(rt);cout<<endl;
	    cout<<"这棵二叉树的高度是:\n" ; 
	    cout<<tree.BinTreeDepth(rt)<<endl;
	    cout<<"这棵二叉树的结点个数是:\n" ; 
	    cout<<tree.count(rt)<<endl;
	} 
	return 0;
}

5、运行结果

 

三、参考资料

1、gogogo_sky_求二叉树的高度/销毁一颗二叉树【递归思想】

2、Clifford A.Shaffer.数据结构与算法分析【M】.北京:电子工业出版社,2013:99-102.

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值