二叉树的一些操作的C++实现。

二叉树的一些操作:先序、中序、后序遍历的非递归实现,层序遍历,树的深度,第K层的节点数,最小公共祖先节点,由先序序列和中序序列还原二叉树。

C++实现,简单起见,没用模板。递归算法比较直观,此处从略,故给出大多是非递归算法。

struct TreeNode
{
	int key;
	TreeNode *lchild;
	TreeNode *rchild;
	TreeNode *pre;
	TreeNode *post;
};
void visit(TreeNode *node)
{
	if(node)
	{
		cout<<node->key<<" ";
	}
}
//非递归的先序遍历
void pre_travel(TreeNode *root)
{
	if(!root)
		return;
	stack<TreeNode*> s;
	TreeNode *p=root;
	s.push(root);
	while(!s.empty())
	{
		p = s.top();
		visit(p);
		s.pop();
		if(p->rchild)
			s.push(p->rchild);
		if(p->lchild)
			s.push(p->lchild);
	}
}
//非递归的中序遍历
void in_travel(TreeNode *root)
{
	stack<TreeNode*> s;
	s.push(root);
	TreeNode *p = root;
	while(!s.empty())
	{
		while((p = s.top()))
			s.push(p->lchild);
		s.pop();
		if(!s.empty())
		{
			p = s.top();
			visit(p);
			s.pop();
			s.push(p->rchild);
		}
	}
}
//非递归的后序遍历
void post_travel(TreeNode *root)
{
	stack<TreeNode*> s;
	stack<bool> s2;
	TreeNode *p=root;
	s.push(p);
	s2.push(false);
	while(!s.empty())
	{
		if((p=s.top()))
		{
			if(s2.top() || (!p->lchild && !p->rchild))
			{
				visit(p);
				s.pop();
				s2.pop();
			}else
			{
				s2.pop();
				s2.push(true);
				if(p->rchild)
				{
					s.push(p->rchild);
					s2.push(false);
				}
				if(p->lchild)
				{
					s.push(p->lchild);
					s2.push(false);
				}
			}	
		}else
			s.pop();
	}
}
//层序遍历
void level_travel(TreeNode *root)
{
	if(!root)
		return;
	queue<TreeNode*> q;
	TreeNode *p=root;
	q.push(root);
	while(!q.empty())
	{
		p = q.front();
		visit(p);
		q.pop();
		if(p->lchild)
			q.push(p->lchild);
		if(p->rchild)
			q.push(p->rchild);
	}
}
//树的层数
int get_levels(TreeNode *root)
{
	int count = 0;
	queue<TreeNode*> q;
	TreeNode *p = root;
	TreeNode *start = root;
	q.push(root);
	while(!q.empty())
	{
		if((p=q.front()))
		{
			if(start && p==start)
			{
				++count;
				if(p->lchild)
					start = p->lchild;
				else
					start = p->rchild;
			}
			q.pop();
			if(p->lchild)
			{
				q.push(p->lchild);
				if(!start)
					start = p->lchild;
			}
			if(p->rchild)
			{
				q.push(p->rchild);
				if(!start)
					start = p->rchild;
			}
		}
	}
	return count;
}
int get_levels_recusion(TreeNode *root)
{
	if(!root)
		return 0;
	return (max(get_levels_recusion(root->lchild),get_levels_recusion(root->rchild))+1);
}
//第k层的节点数
int get_node_count(TreeNode *root,int k)
{
	if(!root || k<=0)
		return 0;
	queue<TreeNode*> q;
	TreeNode *p,*start = root;
	int count = 0;
	int level = 0;
	q.push(root);
	while(!q.empty())
	{
		if((p=q.front()) == start)
		{
			if(level == k)
				return count;
			++level;
			count = 0;
			if(p->lchild)
				start = p->lchild;
			else
				start = p->rchild;
		}
		++count;
		q.pop();
		if(p->lchild)
		{
			q.push(p->lchild);
			if(!start)
				start = p->lchild;
		}
		if(p->rchild)
		{
			q.push(p->rchild);
			if(!start)
				start = p->rchild;
		}
	}
	if(k == level)
		return count;
	return 0;
}
//两节点的最小公共祖先
TreeNode* lcp(int key1,int key2,TreeNode *root)
{
	if(!root)
		return 0;
	stack<int> f;//取值0,1,2.1表示已插入左孩子;2表示已插入右孩子。
	stack<TreeNode*> s1;
	stack<TreeNode*> s2;
	bool find1 = false;
	bool find2 = false;
	TreeNode *p=root;
	s1.push(p);
	s2.push(p);
	f.push(0);
	while((!find1 && !s1.empty()) || (!find2 && !s2.empty()))
	{
		if(!find1)
			p = s1.top();
		else
			p = s2.top();
		if(f.top() == 0)//第一次访问该节点
		{
			if(!find1 && p->key == key1)
				find1 = true;
			if(!find2 && p->key == key2)
				find2 = true;
			if(find1 && find2)
				break;
			f.pop();
			f.push(1);
			if(p->lchild)
			{
				if(!find1)
					s1.push(p->lchild);
				if(!find2)
					s2.push(p->lchild);
				f.push(0);
			}
		}
		if(f.top() == 1)//已访问过该节点和左子树
		{
			f.pop();
			f.push(2);
			if(p->rchild)
			{
				if(!find1)
					s1.push(p->rchild);
				if(!find2)
					s2.push(p->rchild);
				f.push(0);
			}
		}
		if(f.top() == 2)//以访问过该节点和左右子树
		{
			f.pop();
			if(!find1)
				s1.pop();
			if(!find2)
				s2.pop();
		}
	}
	if(find1 && find2)
	{
		while(s1.size()!=s2.size())
			if(s1.size()>s2.size())
				s1.pop();
			else
				s2.pop();
		while(s1.top() != s2.top())
		{
			s1.pop();
			s2.pop();
		}
		return s1.top();
	}
	return 0;
}
//由先序遍历序列和中序遍历序列还原树
TreeNode* pre_in_tree(const string& pre,const string& in,bool &flag)
{
	if(pre.length() != in.length() || pre.length() == 0)
		return 0;
	TreeNode *root = new TreeNode;
	int index = in.find_first_of(pre[0]);
	if(index == -1)
	{
		flag = false;
		return 0;
	}
	root->key = pre[0]-'0';
	root->lchild = pre_in_tree(pre.substr(1,index),in.substr(0,index),flag);
	root->rchild = pre_in_tree(pre.substr(index+1),in.substr(index+1),flag);
	if(flag)
		return root;
	else
		return 0;
}
//转置
TreeNode* transpose(TreeNode *root)
{
	if(root == NULL)
		return NULL;
	stack<TreeNode*> s1;
	stack<bool> s2;
	TreeNode *p = root;
	s1.push(root);
	s2.push(false);
	while(!s1.empty())
	{
		p = s1.top();
		if(!s2.top())
		{
			s2.pop();
			s2.push(true);
			if(p->rchild)
			{
				s1.push(p->rchild);
				s2.push(false);
			}
			if(p->lchild)
			{
				s1.push(p->lchild);
				s2.push(false);
			}
		}else
		{
			TreeNode *q = p->lchild;
			p->lchild = p->rchild;
			p->rchild = q;
			s1.pop();
		}
	}
	return p;
}








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值