码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树

时间:2016-04-23 23:20:11      阅读:656      评论:0      收藏:0      [点我收藏+]

标签:二叉树

介绍二叉树之前呢,我们先来说说树?

树呢,顾名思义,长得像一棵树,不过通常我们画成一颗倒过来的树,根在上,叶在下。还是看图吧。

技术分享

既然说到树了,那就说说树的一些基本概念吧。用图说明。

技术分享

树的存储结构:

技术分享


下面呢,就来介绍树的特殊例子---二叉树

所谓二叉树呢,就是父节点最多有两个孩子。

技术分享

二叉树的存储结构:

(1)数组存储

    数组存储即用一块连续内存来存储二叉树。

技术分享

   若二叉树为满二叉树或者完全二叉树时,用数组存储非常有效,但是对于一般的二叉树来说,效果并不是很好。若要在二叉树中进行增删的话,可能要挪动大量的元素。而使用链表可以克服此困难。

(2)链表存储

技术分享


template <class T>
class BinaryTreeNode//节点
{
public:
	BinaryTreeNode(const T& data)
		:_data(data)
		,_left(NULL)
		,_right(NULL)
	{}
	T _data;//值
	BinaryTreeNode* _left;//左子树
	BinaryTreeNode* _right;//右子树
};

以下述二叉树为例,实现代码:

技术分享

此二叉树的数组表示:int a[10] = {1,2,3,‘#‘,‘#‘,4,‘#‘,‘#‘,5,6}

由图可知:

先根遍历:1,2,3,4,5,6

中根遍历:3,2,4,1,6,5

后根遍历:3,4,2,6,5,1

层次遍历:1,2,5,3,4,6

template <class T>
class BinaryTree
{
public:
	BinaryTree()//无参构造函数
		:_root(NULL)
	{}
	BinaryTree(const T* a,size_t size,const T& invalue)//构造函数
	{
		size_t index = 0;
		_root = _CreatTree(a,size,index,invalue); 
	}
	BinaryTree(const BinaryTree<T>& t)//拷贝构造
	{
		_root = _Copy(t._root);
	}
	BinaryTree<T>& operator=(const BinaryTree<T>& t)//赋值函数
	{
		if(this != &t)
		{
			BinaryTreeNode<T>* tmp = _Copy(t._root);
			_Destory(_root);
			_root = tmp;
		}
		return *this;
	}
	~BinaryTree()//析构
	{
		_Destory(_root);
		_root = NULL;
	}
public:
	void PrevOrder()//先根遍历
	{
		cout<<"先根遍历:";
		_PrevOrder(_root);
		cout<<endl;
	}
	void InOrder()//中根遍历
	{
		cout<<"中根遍历:";
		_InOrder(_root);
		cout<<endl;
	}
	void PostOrder()//后根遍历
	{
		cout<<"后根遍历:";
		_PostOrder(_root);
		cout<<endl;
	}
	void LevelOrder()//层次遍历
	{
		cout<<"层次遍历:";
		_LevelOrder(_root);
	}
	size_t size()
	{
		size_t size = 0;
		_Size(_root,size);
		return size;
	}
	size_t size()//节点个数
	{
		return _Size(_root);
	}
	size_t Depth()//树的深度
	{
		return _Depth(_root);
	}
	size_t LeafSize()//叶子节点个数
	{
		return _LeafSize(_root);
	}
public:
	public:
	BinaryTreeNode<T>* _CreatTree(const T* a,size_t size,size_t &index,const T& invalue)//创建树
	{
		BinaryTreeNode<T>* root = NULL;
		if(index < size && a[index] != invalue)
		{
			root = new BinaryTreeNode<T>(a[index]);
			root->_left = _CreatTree(a,size,++index,invalue);
			root->_right = _CreatTree(a,size,++index,invalue);
		}
		return root;
	}

	void _PrevOrder(BinaryTreeNode<T>* root)//先根遍历
	{
		if(root == NULL)
			return;
		else
		{
			cout<<root->_data<<" ";
			_PrevOrder(root->_left);
			_PrevOrder(root->_right);
		}
	}

	void _InOrder(BinaryTreeNode<T>* root)//中根遍历
	{
		if(root == NULL)//递归终止条件
			return;
		else
		{
			_InOrder(root->_left);
			cout<<root->_data<<" ";
			_InOrder(root->_right);
		}
	}
	
	void _PostOrder(BinaryTreeNode<T>* root)//后根遍历
	{
		if(root == NULL)
			return;
		else
		{
			_PostOrder(root->_left);
			_PostOrder(root->_right);
			cout<<root->_data<<" ";
		}
	}

	void _Destory(BinaryTreeNode<T>* root)//析构---相当于后序删除
	{
		if(root == NULL)
			return;
		else
		{
			_Destory(root->_left);
			_Destory(root->_right);
			delete root;
		}
	}

	size_t _Size(BinaryTreeNode<T>* root)//节点的个数
	{
		size_t count = 0;
		if(root == NULL)
			return 0;
		count = _Size(root->_left) + _Size(root->_right);
		return count+1;	
	}
	
	size_t _Depth(BinaryTreeNode<T>* root)//树的深度
	{
		size_t left = 0;
		size_t right = 0;
		size_t max = 0;
		if(root == 0)
			return 0;
		else
		{
			left = _Depth(root->_left);
			right = _Depth(root->_right);
			max = left>right?left:right;
			return max+1;
		}	
	}
	
	size_t _LeafSize(BinaryTreeNode<T>* root)//叶子节点的个数
	{
		size_t count = 0;
		if(root == NULL)
			return 0;
		
		if(root && root->_left == NULL && root->_right == NULL)
			return 1;

		count = _LeafSize(root->_left)+_LeafSize(root->_right);
		return count;
	}
	
	//size_t _LeafSize(BinaryTreeNode<T>* root)//遍历整个树来确定叶子节点的个数
	//{
	//	static size_t count = 0;
	//	if(root == NULL)
	//		return 0;
	//	if(root->_left == NULL && root->_right == NULL)
	//	{
	//		++count;
	//	}
	//	_LeafSize(root->_left);
	//	_LeafSize(root->_right);
	//	return count;
	//}
	
	BinaryTreeNode<T>* _Copy(BinaryTreeNode<T>* root)
	{
		BinaryTreeNode<T>* newroot = NULL;
		if(root != NULL)
		{
			newroot = new BinaryTreeNode<T>(root->_data);
			
			newroot->_left = _Copy(root->_left);
			newroot->_right = _Copy(root->_right);
			
		}
		return newroot;
	}

	void _LevelOrder(BinaryTreeNode<T>* root)//层次遍历
	{
		queue<BinaryTreeNode<T>*> q;
		if(root == NULL)
			return;
		if(root != NULL)
		{
			q.push(root);
		}
		while(!q.empty())
		{
			BinaryTreeNode<T>* node = q.front();
			cout<<node->_data<<" ";
			if(node->_left != NULL)
			{
				q.push(node->_left);
			}
			if(node->_right != NULL)
			{
				q.push(node->_right);
			}
			q.pop();
		}
		cout<<endl;
	}

	void PrevOrder_NonR()//非递归的先根遍历
	{
		cout<<"非递归的先根遍历:";
		BinaryTreeNode<T>* cur = _root;
		stack<BinaryTreeNode<T>*> s;
		if(cur != NULL)
		{
			s.push(cur);
			cout<<s.top()->_data<<" ";
			s.pop();
		}
		while(!s.empty() || cur)
		{	
			if(cur->_right != NULL)
			{
				s.push(cur->_right);
			}
			if(cur->_left != NULL)
			{
				s.push(cur->_left);
			}
			if(!s.empty())
			{
				cout<<s.top()->_data<<" ";
				cur = s.top();
				s.pop();
			}
			else
			{
				cur = NULL;
			}
		}
		cout<<endl;
	}
	void INOrder_NonR()//非递归的中根遍历
	{
		cout<<"非递归的中根遍历:";
		if(_root == NULL)
			return;
		BinaryTreeNode<T>* cur = _root;
		stack<BinaryTreeNode<T>*> s;
		while(cur || !s.empty())
		{
			while(cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			BinaryTreeNode<T>* top = s.top();
			cout<<top->_data<<" ";
			s.pop();
			cur = top->_right;
		}
		cout<<endl;
	}
	void PostOrder_NonR()//非递归的后根遍历
	{
		cout<<"非递归的后根遍历:";
		BinaryTreeNode<T>* cur = _root;
		BinaryTreeNode<T>* prev = NULL;
		stack<BinaryTreeNode<T>*> s;
		BinaryTreeNode<T>* top = NULL; 
		if(_root == NULL)
			return;
		while(cur || !s.empty())
		{
			while(cur)
			{
				while(cur)
				{
					s.push(cur);
					cur = cur->_left; 
				}
				top = s.top();
				cur = top->_right;	
			}
			if(s.top()->_right == NULL)
	     	{
				cout<<s.top()->_data<<" ";
				prev = s.top();
				s.pop();
			}
			   if(!s.empty())
			   {
					if(s.top()->_right == prev)
					{
						cout<<s.top()->_data<<" ";
						prev = s.top();
						s.pop();
					}
					if(!s.empty())
					{
						cur = s.top()->_right;
					}
					else
					{
					   cur = NULL;
				    }
			   }	  
		}
		cout<<endl;
	}
protected:
	BinaryTreeNode<T>* _root;//根节点
};

测试函数:

void Test()
{
	int a[10] = {1,2,3,‘#‘,‘#‘,4,‘#‘,‘#‘,5,6};
	BinaryTree<int> b(a,10,‘#‘);
	b.PrevOrder();
	b.InOrder();
	b.PostOrder();
	//b.~BinaryTree();
	int ret1 = b.size();//节点个数
	int ret2 = b.LeafSize();//叶子节点
	int ret3 = b.Depth();//深度
	cout<<ret1<<endl;
	cout<<ret2<<endl;
	cout<<ret3<<endl;
	BinaryTree<int> b1(b);//拷贝构造
	b1.PrevOrder();

	BinaryTree<int> b2;
	b2 = b1;//赋值
	b2.PrevOrder();
	b2.LevelOrder();
	b2.PrevOrder_NonR();
	b2.INOrder_NonR();
	b2.PostOrder_NonR();
}

测试结果:

技术分享

测试结果和由图得出的结果相同。

二叉树

标签:二叉树

原文地址:http://10810429.blog.51cto.com/10800429/1767038

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!