(题目见书或者网络原题)
给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示
示例:
输入:{8,6,10,5,7,9,11},8
返回:9
解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来
方法一:
static int count_1 = 0;
static struct TreeLinkNode* ret = NULL;
void inOrder(struct TreeLinkNode* root, int val){
if(root == NULL){
return;
}
inOrder(root->left, val);
if(count_1){
ret = root;
count_1 = 0;
return;
}
if(root->val == val){
count_1 = 1;
}
inOrder(root->right, val);
}
struct TreeLinkNode* GetNext(struct TreeLinkNode* pNode ) {
struct TreeLinkNode* root = pNode;
while(root -> next != NULL){
root = root -> next;
}
inOrder(root, pNode->val);
return ret;
}
方法一是自己写的,思路是简单的找到二叉树的root节点,然后进行正常的中序遍历,找到这个值返回对应节点,找不到则返回NULL。思路简单便于理解,相比来说,时间复杂度也是o(n)级别,但是比下面方法要长一些。
方法二:
struct TreeLinkNode* GetNext(struct TreeLinkNode* pNode ) {
struct TreeLinkNode* root = pNode;
if(root->right != NULL){
root = root->right;
while(root->left){
root = root->left;
}
return root;
}else if(root->next != NULL){
if(root->next->left != NULL && root->next->left == root){
return root->next;
}else{
while(root->next != NULL){
if(root->next->left != NULL && root->next->left == root){
return root->next;
}
root = root->next;
}
}
}
return NULL;
}
方法二是对于中序遍历进行细致分析
情况一:如果有右子支,那么右子支的最左节点就是需要返回的节点。
情况二:如果没有右子支,则需要寻找父节点。父节点为右父节点,则返回该父节点。
情况三:如果父节点为左父节点,则寻找第一个右父节点,找到则返回该父节点。