剑指offer8: 二叉树的下一个节点

第一种情况(1)当节点有右子树,先找到其右子树,然后一直往左找,最后的那个叶子结点就是其下一个节点(如b的下一个节点为其右子树e的左子树h)
第二种情况(2)当节点没有右子树,但是是其双亲结点的左子树,那么它的下一个节点为其双亲结点(如d的下一个节点为b)
第三种情况(3)当节点既没有右子树,还不是双亲结点的左子树,一直向上递归双亲结点,直到有个双亲结点是该双亲结点的左子树,(如i的下一个节点为a,i向上递归,i->e>b,b是a的左子树,所以a为i的下一个节点) 

题目中考虑的三种情况也就是中序遍历输出二叉树过程中的一个思路。

中序遍历刚开始,先向左遍历,然后第一个是d,根据(2),下一个是b ->(1)-> h ->(2)-> e ->(1)-> i ->(3)-> a  ........ 

 

​
#include<iostream>
using namespace std;

struct TreeNode
{
	char data;
	
	TreeNode* lchild;
	TreeNode* rchild;
	TreeNode* parent;
};

TreeNode* CreateTree(TreeNode* par)  //通过前序遍历建树 (dbheiafcg) 
{
	TreeNode* root=new TreeNode;
	 
	root->parent=par;  //指向其双亲结点,便于后面情况的处理 
	
	char ch=getchar();
	
	if(ch=='.')
	{
		return NULL;
	}
	
	else
	{
		root->data = ch;
		
		root->lchild=CreateTree(root);
	
		root->rchild=CreateTree(root);
		
		return root;
	}
}

void inOrder(TreeNode* root) //中序输出 
{
	if(root)
	{
	inOrder(root->lchild);
	
	cout<<root->data;
	
	inOrder(root->rchild);
    }
}

TreeNode* findNode(TreeNode* root,char ch)  //找到需要找下一个节点的节点(要找b的下一个节点h,那么几样要先找到b)
{	
    if(root==NULL) return NULL;
    
	if(root->data==ch)
	{
		return root;
	}
	
	else
	{
		TreeNode* node=findNode(root->lchild,ch);
		if(node!=NULL)
		{
			return node;
		}
		
		node=findNode(root->rchild,ch);
		if(node!=NULL)
		{
			return node;
		}
	}
	
	return NULL;
}

void findNext(TreeNode* root,char ch)  //在中序遍历顺序中,找到节点的下一个节点 
{
	TreeNode* ob=findNode(root,ch); //目标节点 
	
	TreeNode* ob_next=new TreeNode; //目标节点的下一个节点 
	
	if(ob->rchild!=NULL) //如果ob有右子树,那么其下一个节点为其右子树的最左子树; 
	                     //如b的下一个节点为其右子树e的左子树h
	{
	    ob_next=ob->rchild;
		
		while(ob_next->lchild!=NULL)
		{
			ob_next=ob_next->lchild;
		}
		
		cout<<ob_next->data;
	}
	
	
	else if(ob->rchild==NULL&&ob->parent->lchild==ob)  //如果ob没右子树,但是是其双亲结点的左子树,那么其下一个节点就是其双亲结点 
	                                                   // 如d的下一个节点为b 
	{
		ob_next=ob->parent;
		
		cout<<ob_next->data;
	}
	
	else  //如果ob没有右子树,也不是双亲结点的左子树,那么就向上递归双亲结点,直到找到某个双亲节点是该双亲节点的左子树
	      //如i的下一个节点为a(i向上递归,i->e>b,b是a的左子树,所以a为i的下一个节点) 
	{
		ob_next=ob->parent;
		
		while(ob_next!=ob_next->parent->lchild) 
		{
			ob_next=ob_next->parent;
		}
		
		ob_next=ob_next->parent;
		
		cout<<ob_next->data;
	}
}

int main()
{
	TreeNode* par=new TreeNode; //没有很大的实际意义,单纯当做根节点指向的双亲结点 
	
	TreeNode* root=CreateTree(par);
	
	inOrder(root);
	
	cout<<endl;
	
	findNext(root,'i');
	
	return 0;
}

​

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值