目录
1.题目
查找值为x的节点并返回节点的地址
代码模板
cpp
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
}
2.分析
分类讨论各种情况
1.节点为NULL,返回NULL
2.节点值为x,找到了,返回其地址
3.节点值不为,没找到,继续递归查找
大概的框架
cpp
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
//继续递归
//......
}
关键部分(继续递归)的详解
根节点查不到,分别去查左右子树,若查到则返回地址,查不到返回NULL
双路递归思想
cpp
//继续递归
BTNode* lret = BinaryTreeFind(root->left, x);
if (lret)
return lret;
BTNode* rret = BinaryTreeFind(root->right, x);
if (rret)
return rret;
return NULL;
递归调用展开图
以下面这张图为例子,比如查找5
(注:递归调用展开图较大,建议查看大图)
注:CSDN会压缩图片画质,无损bmp图片链接(大小 36.5M) 见https://pan.baidu.com/s/1VT9lg2xdofExMCjS8oIOzQ?pwd=xs7n)
3.测试结果
main.c写入以下代码
cpp
#include "Tree.h"
int main()
{
BTNode* root = CreateTree();
BTDataType x = 2;
printf("x=5,address=%p\n", BinaryTreeFind(root, 5));
printf("x=0,address=%p\n", BinaryTreeFind(root, 0));
return 0;
}
打印的地址和监视窗口中查看到的地址一样
其他写法
cpp
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
BTNode* lret = BinaryTreeFind(root->left, x);
if (lret)
return lret;
return BinaryTreeFind(root->right, x);
}
4.结论
由分析可知,root->data若等于x则会层层返回至整个树的根节点
5.注意事项
不推荐的写法
cpp
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
if (BinaryTreeFind(root->left, x))
return BinaryTreeFind(root->left, x);
if (BinaryTreeFind(root->right, x))
return BinaryTreeFind(root->right, x);
return NULL;
}
BinaryTreeFind(root->left, x)和BinaryTreeFind(root->right, x)各被调用两次,找到x是第一次,返回x的值是第二次,时间复杂度较高,尤其当二叉树的节点过多,二叉树的结构复杂时,执行效率低下,最好保存返回值免得重复调用