剑指offer面试题(8)——二叉树的下一个节点

        题目:给定一棵二叉树和其中的一个节点,如何找出中序遍历顺序的下一个节点? 树中的节点除了有两个分别指向左右子节点的指针以外,还有一个指向父节点的指针。

        如下图所示的一颗二叉树,中序遍历序列是{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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值