题目:给定一棵二叉树和其中的一个节点,如何找出中序遍历顺序的下一个节点? 树中的节点除了有两个分别指向左右子节点的指针以外,还有一个指向父节点的指针。
如下图所示的一颗二叉树,中序遍历序列是{d,b,h,e,i,a,f,c,g};下面将以这棵树为例。其中实线表示父节点指向子节点的指针,虚线表示子节点指向父节点的指针。
二叉树节点定义如下:
struct BinaryTreeNode
{
char m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode* m_pParent;
};
解题思路
首先根据中序遍历的特点,有如下三种情况:
1、如果一个节点有右子树,那么它的下一个节点就是它的右子树的最左子结点。也就是说,从右子节点出发一直沿着指向左子节点的指针,我们就可以找到它的下一个节点。
2、如果一个节点没有右子树,那么如果它是其父节点的左子节点,则它的下一个节点就是它的父节点。3、如果一个节点既没有右子树,也不是父节点的左子结点,那么我们沿着指向父节点的指针一直向上遍历,直到找到一个节点,该节点是其父节点的左子节点。如果这样的节点存在,那么该节点的父节点就是我们要找的下一个节点。
上述三种情况实现主要代码如下:
#include "BinaryTree.h"
#include <cstdio>
#include"stdlib.h"
BinaryTreeNode* FindNextNode(BinaryTreeNode* pNode)
{
if (pNode == nullptr)
return nullptr;
BinaryTreeNode* pNext = nullptr;
if (pNode->m_pRight != nullptr)
{
BinaryTreeNode* pRight = pNode->m_pRight;
while (pRight->m_pLeft != nullptr)
pRight = pRight->m_pLeft;
pNext = pRight;
}
else if (pNode->m_pParent != nullptr)
{
BinaryTreeNode* pCurrent = pNode;
BinaryTreeNode* pParent = pNode->m_pParent;
while (pParent != nullptr && pCurrent == pParent->m_pRight)
{
pCurrent = pParent;
pParent = pParent->m_pParent;
}
pNext = pParent;
}
return pNext;
}
// ====================测试代码====================
void Test(char* testName, BinaryTreeNode* pNode, BinaryTreeNode* expected)
{
if (testName != nullptr)
printf("%s begins: ", testName);
BinaryTreeNode* pNext = FindNextNode(pNode);
if (pNext == expected)
printf("Passed.\n");
else
printf("FAILED.\n");
}
下面附上二叉树创建销毁等相关函数的实现。
头文件:
//BinaryTree.h
#pragma once
struct BinaryTreeNode
{
char m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode* m_pParent;
};
BinaryTreeNode* CreateBinaryTreeNode(char value);
void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight);
void PrintTreeNode(const BinaryTreeNode* pNode);
void PrintTree(const BinaryTreeNode* pRoot);
void DestroyTree(BinaryTreeNode* pRoot);
实现文件:
//BinaryTree.cpp
#include <cstdio>
#include "BinaryTree.h"
BinaryTreeNode* CreateBinaryTreeNode(char value)
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = nullptr;
pNode->m_pRight = nullptr;
pNode->m_pParent = nullptr;
return pNode;
}
void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
{
if(pParent != nullptr)
{
pParent->m_pLeft = pLeft;
pParent->m_pRight = pRight;
if (pLeft != nullptr)
pLeft->m_pParent = pParent;
if (pRight != nullptr)
pRight->m_pParent = pParent;
}
}
void PrintTreeNode(const BinaryTreeNode* pNode)
{
if(pNode != nullptr)
{
printf("value of this node is: %d\n", pNode->m_nValue);
if(pNode->m_pLeft != nullptr)
printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);
else
printf("left child is nullptr.\n");
if(pNode->m_pRight != nullptr)
printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);
else
printf("right child is nullptr.\n");
}
else
{
printf("this node is nullptr.\n");
}
printf("\n");
}
void PrintTree(const BinaryTreeNode* pRoot)
{
PrintTreeNode(pRoot);
if(pRoot != nullptr)
{
if(pRoot->m_pLeft != nullptr)
PrintTree(pRoot->m_pLeft);
if(pRoot->m_pRight != nullptr)
PrintTree(pRoot->m_pRight);
}
}
void DestroyTree(BinaryTreeNode* pRoot)
{
if(pRoot != nullptr)
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;
delete pRoot;
pRoot = nullptr;
DestroyTree(pLeft);
DestroyTree(pRight);
}
}
测试用例1
// a
// b c
// d e f g
// h i
void Test1_7()
{
BinaryTreeNode* pNode_a = CreateBinaryTreeNode('a');
BinaryTreeNode* pNode_b = CreateBinaryTreeNode('b');
BinaryTreeNode* pNode_c = CreateBinaryTreeNode('c');
BinaryTreeNode* pNode_d = CreateBinaryTreeNode('d');
BinaryTreeNode* pNode_e = CreateBinaryTreeNode('e');
BinaryTreeNode* pNode_f = CreateBinaryTreeNode('f');
BinaryTreeNode* pNode_g = CreateBinaryTreeNode('g');
BinaryTreeNode* pNode_h = CreateBinaryTreeNode('h');
BinaryTreeNode* pNode_i = CreateBinaryTreeNode('i');
ConnectTreeNodes(pNode_a, pNode_b, pNode_c);
ConnectTreeNodes(pNode_b, pNode_d, pNode_e);
ConnectTreeNodes(pNode_c, pNode_f, pNode_g);
ConnectTreeNodes(pNode_e, pNode_h, pNode_i);
Test("Test1", pNode_d, pNode_b);
Test("Test2", pNode_b, pNode_h);
Test("Test3", pNode_e, pNode_i);
Test("Test4", pNode_i, pNode_a);
Test("Test5", pNode_a, pNode_f);
Test("Test6", pNode_f, pNode_c);
Test("Test7", pNode_g, nullptr);
DestroyTree(pNode_a);
}
测试用例2
// a
// b
// c
// d
void Test8_11()
{
BinaryTreeNode* pNode_a = CreateBinaryTreeNode('a');
BinaryTreeNode* pNode_b = CreateBinaryTreeNode('b');
BinaryTreeNode* pNode_c = CreateBinaryTreeNode('c');
BinaryTreeNode* pNode_d = CreateBinaryTreeNode('d');
ConnectTreeNodes(pNode_a, pNode_b, nullptr);
ConnectTreeNodes(pNode_b, pNode_c, nullptr);
ConnectTreeNodes(pNode_c, pNode_d, nullptr);
Test("Test8", pNode_a, nullptr);
Test("Test9", pNode_b, pNode_a);
Test("Test10",pNode_c, pNode_b);
Test("Test11",pNode_d, pNode_c);
DestroyTree(pNode_a);
}
测试用例3
// a
// b
// c
// d
void Test12_15()
{
BinaryTreeNode* pNode_a = CreateBinaryTreeNode('a');
BinaryTreeNode* pNode_b = CreateBinaryTreeNode('b');
BinaryTreeNode* pNode_c = CreateBinaryTreeNode('c');
BinaryTreeNode* pNode_d = CreateBinaryTreeNode('d');
ConnectTreeNodes(pNode_a, nullptr, pNode_b );
ConnectTreeNodes(pNode_b, nullptr, pNode_c );
ConnectTreeNodes(pNode_c, nullptr, pNode_d );
Test("Test12", pNode_d, nullptr);
Test("Test13", pNode_c, pNode_d);
Test("Test14", pNode_b, pNode_c);
Test("Test15", pNode_a, pNode_b);
DestroyTree(pNode_a);
}
测试用例4
//只有一个节点
void Test16()
{
BinaryTreeNode* pNode_a = CreateBinaryTreeNode('a');
Test("Test16", pNode_a, nullptr);
DestroyTree(pNode_a);
}