题目描述

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

解题思路

  • 定义一个寻找根结点的函数,找到根结点,如果pNode本身为根结点,直接返回。
  • 定义一个中序遍历函数,并用vector容器存储二叉树中序遍历序列。
  • 找到容器中和pNode匹配的结点,返回结点的下一个结点即可。结点为空返回空,pNode在vector中的最后一个位置返回空。

代码实现

/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {

}
};
*/
class Solution {
public:
TreeLinkNode* FindpRoot(TreeLinkNode* pNode) // 寻找pNode所在二叉树的根结点
{
if(pNode == NULL) // 结点为空 返回NULL
return NULL;
if(pNode->next == NULL) // pNode为根结点直接返回该结点
return pNode;
TreeLinkNode* pRoot = pNode->next;
for( ;pRoot->next; pRoot = pRoot->next);
return pRoot;
}

void InOrderBiTree(TreeLinkNode* pRoot, vector<TreeLinkNode*> &vpNode) // 中序遍历二叉树
{
if(pRoot)
{
if(pRoot->left)
InOrderBiTree(pRoot->left, vpNode);
vpNode.push_back(pRoot);
if(pRoot->right)
InOrderBiTree(pRoot->right, vpNode);
}
}

TreeLinkNode* FindNextNode(TreeLinkNode* pNode, vector<TreeLinkNode*> &vpNode)
{
if(pNode == NULL) // 结点为空返回空
return NULL;
if(vpNode.empty()) // 容器为空 返回空
return NULL;
vector<TreeLinkNode*>::iterator iter = vpNode.begin();
for(; iter != vpNode.end(); iter++)
{
if(*iter == pNode)
break;
}
if((++iter) == vpNode.end()) // pNode为最后一个结点 返回空
return NULL;
return *iter; // 返回pNode的下一个结点指针
}

TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode == NULL)
return NULL;
TreeLinkNode* pRoot = FindpRoot(pNode);
vector<TreeLinkNode*> vpNode;
InOrderBiTree(pRoot, vpNode);

return FindNextNode(pNode, vpNode);
}
};

毕竟是C++,还是多用一些泛型算法比较好,比如上述代码部分的:

for(; iter != vpNode.end(); iter++)
{
if(*iter == pNode)
break;
}

可以改成如下形式:

iter = find(vpNode.begin(), vpNode.end(), pNode);

尽量多的使用泛型编程,要逐渐适应C到C++的转变。

主函数部分

又在VS2013上实现了一遍

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<vector>
using namespace std;

struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {

}
};

TreeLinkNode* CreateTree() // 创建这种二叉树
{
TreeLinkNode* root = new TreeLinkNode(5); // 注意new的用法 初始化后必须赋值
root->next = NULL;
TreeLinkNode* left1 = new TreeLinkNode(3);
left1->next = root;
TreeLinkNode* right1 = new TreeLinkNode(7);
right1->next = root;
root->left = left1; // 赋值问题 老是出错
root->right = right1;
TreeLinkNode* left2 = new TreeLinkNode(2);
TreeLinkNode* right2 = new TreeLinkNode(4);
left1->left = left2;
left2->next = left1;
left1->right = right2;
right2->next = left1;
TreeLinkNode* left3 = new TreeLinkNode(6);
TreeLinkNode* right3 = new TreeLinkNode(8);
right1->left = left3;
left3->next = right1;
right1->right = right3;
right3->next = right1;
return root;
}

void printBiTree(vector<TreeLinkNode*> &vpNode) // 打印数组
{
if (vpNode.empty())
{
return;
}
vector<TreeLinkNode*>::iterator iter = vpNode.begin();
for (; iter != vpNode.end(); iter++)
{
cout << (*iter)->val << " ";
}
cout << endl;
}

TreeLinkNode* FindpRoot(TreeLinkNode* pNode) // 返回该结点所在树的根结点
{
if (pNode == NULL)
return NULL;
if (pNode->next == NULL)
{
return pNode;
}
TreeLinkNode* pRoot = pNode->next;
for (; pRoot->next; pRoot = pRoot->next);
return pRoot;
}

void InOrderBiTree(TreeLinkNode* pRoot, vector<TreeLinkNode*> &vpNode) // 中序遍历二叉树 结果存在vector容器中
{
if (pRoot)
{
if (pRoot->left)
InOrderBiTree(pRoot->left, vpNode);
vpNode.push_back(pRoot);
if (pRoot->right)
InOrderBiTree(pRoot->right, vpNode);
}
}

TreeLinkNode* FindNextNode(TreeLinkNode* pNode, vector<TreeLinkNode*> &vpNode)
{
if (pNode == NULL)
return NULL;
if (vpNode.empty())
return NULL;
vector<TreeLinkNode*>::iterator iter = vpNode.begin();
for (; iter != vpNode.end(); iter++)
{
if (*iter == pNode)
break;
}
if ((++iter) == vpNode.end())
return NULL;
return *iter;
}

TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if (pNode == NULL)
return NULL;
TreeLinkNode* pRoot = FindpRoot(pNode);
vector<TreeLinkNode*> vpNode;
InOrderBiTree(pRoot, vpNode);

return FindNextNode(pNode, vpNode);
}

void main()
{
TreeLinkNode* pRoot = CreateTree();
vector<TreeLinkNode*> v;
InOrderBiTree(pRoot, v);
printBiTree(v); // 2 3 4 5 6 7 8
TreeLinkNode* pNode = pRoot->right->right; // 注意这里是可以改变的
if (GetNext(pNode) == NULL)
{
cout << "我是空,没有指向的值!" << endl;
}
else
{
cout << GetNext(pNode)->val << endl;
}

system("pause");
return;
}
/* 当输入的结点是8时,
2 3 4 5 6 7 8
我是空,没有指向的值!
请按任意键继续. . .
*/
/* 当输入结点为5时
2 3 4 5 6 7 8
6
请按任意键继续. . .
*/

一定还有不引入vector的方法,to be continued…