二叉树的知识点的总结


1)二叉树的前序,中序,后序,层次遍历的原理和实现

void _PreOrder(BinaryTreeNode<T> *root)
	{
		if(root == NULL){
			return;
		}
		cout<<root->data<<" ";
		_PreOrder(root->_left);
		_PreOrder(root->_right);
	}
	void _InOrder(BinaryTreeNode<T> *root)
	{
		if(root == NULL){
			return;
		}
		_InOrder(root->_left);
		cout<<root->data<<" ";
		_InOrder(root->_right);
	}
	void _PostOrder(BinaryTreeNode<T> *root)
	{
		if(root == NULL){
			return;
		}
		_PostOrder(root->_left);
		_PostOrder(root->_right);
		cout<<root->data<<" ";
	}
	void _LevelOrder(BinaryTreeNode<T> *root)
	{
		if(root == NULL){
			cout<<"NULL";
			return;
		}
		queue<BinaryTreeNode<T> *> s;
		s.push(root);
		while(!s.empty()){
			BinaryTreeNode<T> *tmp = s.front();
			cout<<tmp->data<<" ";
			s.pop();
			if(tmp->_left != NULL){
				s.push(tmp->_left);
			}
			if(tmp->_right != NULL){
				s.push(tmp->_right);
			}
		}
	}


非递归实现:


void PreOrder_NonR()
	{
		stack<BinaryTreeNode<T> *> s;
		if(_root == NULL){
			return;
		}
		s.push(_root);
		while(!s.empty()){
			BinaryTreeNode<T> *top =s.top();
			s.pop();
			cout<<top->data<<" ";
			if(top->_right != NULL)
				s.push(top->_right);
			if(top->_left != NULL)
				s.push(top->_left);
		}
		cout<<endl;
	}
	void InOrder_NonR()
	{
		stack<BinaryTreeNode<T> *> s;
		BinaryTreeNode<T> *cur = _root;
		if(_root == NULL){
			return;
		}
		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()
	{
		stack<BinaryTreeNode<T> *> s;
		BinaryTreeNode<T> *cur = _root;
		BinaryTreeNode<T> *PreVisited = NULL;
		if(_root == NULL){
			return;
		}
		while(cur || !s.empty()){
			while(cur){
				s.push(cur);
				cur = cur->_left;
			}
			BinaryTreeNode<T> *top = s.top();
			if(top->_right == NULL || top->_right == PreVisited){
				cout<<top->data<<" ";
				s.pop();
				PreVisited = top;
			}else{
		        cur = top->_right;
			}
		}
	}

2)二叉树的线索化的实现,为什么要有线索化?

二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。

为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。

enum Tag{
	THREAD,
	LINK,
};
template<typename T>
struct BinaryTreeNode{
	T data;
	BinaryTreeNode *_left;
	BinaryTreeNode *_right;
	Tag _leftTag;
	Tag _rightTag;

	BinaryTreeNode(T _data)
		:data(_data)
		,_left(NULL)
		,_right(NULL)
		,_leftTag(LINK)
		,_rightTag(LINK)
	{}
};

线索化:

<span style="white-space:pre">	</span>void _InOrderThreading(BinaryTreeNode<T> *cur,BinaryTreeNode<T> * & prev)
	{
		if(cur == NULL)
			return;
		_InOrderThreading(cur->_left,prev);
		if(cur->_left == NULL)   //如果左为空,对左进行线索化
		{
			cur->_leftTag = THREAD;
			cur->_left = prev;
		}
		if(prev && prev->_right == NULL)   //如果右为空,对右进行线索化
		{
			prev->_rightTag = THREAD;
			prev->_right = cur;
		}
		prev = cur;
		_InOrderThreading(cur->_right,prev);
	}

	void _PreOrderThreading(BinaryTreeNode<T> *cur,BinaryTreeNode<T> * & prev)
	{
		if(cur == NULL)
			return;
		if(cur->_left == NULL)   //如果左为空,对左进行线索化
		{
			cur->_leftTag = THREAD;
			cur->_left = prev;
		}
		if(prev && prev->_right == NULL)   //如果右为空,对右进行线索化
		{
			prev->_rightTag = THREAD;
			prev->_right = cur;
		}
		prev = cur;
		if(cur->_leftTag == LINK)
			_PreOrderThreading(cur->_left,prev);

		if(cur->_rightTag == LINK)
			_PreOrderThreading(cur->_right,prev);
	}
	void _PostOrderThreading(BinaryTreeNode<T> *cur,BinaryTreeNode<T> * & prev)
	{
		if(cur == NULL)
			return;
		
		_PostOrderThreading(cur->_left,prev);
				_PostOrderThreading(cur->_right,prev);

		if(cur->_left == NULL)   //如果左为空,对左进行线索化
		{
			cur->_leftTag = THREAD;
			cur->_left = prev;
		}
		if(prev && prev->_right == NULL)   //如果右为空,对右进行线索化
		{
			prev->_rightTag = THREAD;
			prev->_right = cur;
		}
		prev = cur;
	}

线索化后的遍历

<span style="white-space:pre">	</span>void InOrderThd()
	{
		BinaryTreeNode<T> *cur = _root;
		while(cur)
		{
			while( cur && cur->_leftTag == LINK) //找到最左结点
				cur = cur->_left;
			cout<<cur->data<<" ";

			if(cur->_rightTag == THREAD){
				cur = cur->_right;
				cout<<cur->data<<" ";
			}

			cur = cur->_right;
		}
	}

<span style="white-space:pre">	</span>void PreOrderThd()
	{
		BinaryTreeNode<T> *cur = _root;
		while(cur)
		{
			while(cur->_leftTag == LINK){
				cout<<cur->data<<" ";
				cur = cur->_left;
			}
			cout<<cur->data<<" ";
			cur = cur->_right;
		}
	}

<span style="white-space:pre">	</span>void PostOrderThd()
	{
		stack<BinaryTreeNode<T> *> s;
		BinaryTreeNode<T> *cur = _root;
		while(cur)
		{
			while(cur->_rightTag == LINK){
				s.push(cur);
				cur = cur->_right;
			}

			s.push(cur);
			cur = cur->_left;		    
		}
		while(s.size() > 0){
			BinaryTreeNode<T> *tmp = s.top();
			cout<<tmp->data<<" ";
			s.pop();
		}
	}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值