这几天写二叉树时出现了一个严重的bug,找bug浪费了好几天的时间,期间都想放弃了但最后坚持了下来,最后发现了一个严重的知识点漏洞。还好多亏我坚持了下来,所以首先想说的是以后遇见bug时一定要耐着心查找,一定要坚持,不要怕浪费时间。
下面是我的错误代码:
#include"stdafx.h"
#include<iostream>
using namespace std;
struct TreeNode
{
char data;
struct TreeNode *lchild;
struct TreeNode *rchild;
};
void CreateTree(TreeNode *T);
void PrintfTree(TreeNode *T);
int BitTreeDep(TreeNode *T);
int main()
{
TreeNode *tree = nullptr;
cout << "请输入节点数据:" << endl;
/*错误*/
CreateTree(tree);
PrintfTree(tree);
return 0;
}
void CreateTree(TreeNode *T)
{
char ch;
cin >> ch;
if (ch == '#')
{
T = nullptr;
}
else
{
T = new TreeNode;
if (!T)
exit(OVERFLOW);
T->data = ch;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}
//前序遍历二叉树
void PrintfTree(TreeNode *T)
{
if (T == nullptr)
return;
cout << T->data;
PrintfTree(T->lchild);
PrintfTree(T->rchild);
}
//返回二叉树的深度
int BitTreeDep(TreeNode *T)
{
int i, j;
if (!T)
return 0;
if (T->lchild)
i = BitTreeDep(T->lchild);
else
i = 0;
if (T->rchild)
j = BitTreeDep(T->rchild);
else
j = 0;
return i > j ? i + 1 : j + 1;
}
错误的地方在于向函数中传递指针,在向函数参数传递值时,函数都会构造这个值的副本,传递指针也不例外,在这个例子中,构造了tree指针的副本T,因为tree指向nullptr,所以T指针也指向nullptr,在函数体内为T重新分配了一段堆内存,所以T重新指向这段堆内存,但是tree还是指向nullptr,所以函数返回时会删除这个副本T,所以tree还是没变一直是nullptr。
修改后的代码
#include"stdafx.h"
#include<iostream>
using namespace std;
struct TreeNode
{
char data;
struct TreeNode *lchild;
struct TreeNode *rchild;
};
void CreateTree(TreeNode **T);
void PrintfTree(TreeNode *T);
int BitTreeDep(TreeNode *T);
int main()
{
TreeNode *tree = nullptr;
TreeNode* *p = &tree;
cout << "请输入节点数据:" << endl;
CreateTree(p);
PrintfTree(tree);
return 0;
}
void CreateTree(TreeNode **T)
{
char ch;
cin >> ch;
if (ch == '#')
{
*T = nullptr;
}
else
{
*T = new TreeNode;
if (!(*T))
exit(OVERFLOW);
(*T)->data = ch;
CreateTree(&((*T)->lchild));
CreateTree(&((*T)->rchild));
}
}
//前序遍历二叉树
void PrintfTree(TreeNode *T)
{
if (T == nullptr)
return;
cout << T->data;
PrintfTree(T->lchild);
PrintfTree(T->rchild);
}
//返回二叉树的深度
int BitTreeDep(TreeNode *T)
{
int i, j;
if (!T)
return 0;
if (T->lchild)
i = BitTreeDep(T->lchild);
else
i = 0;
if (T->rchild)
j = BitTreeDep(T->rchild);
else
j = 0;
return i > j ? i + 1 : j + 1;
}
代码说明:
因为在函数中为指针开辟内存空间是传递给参数的指针的副本指向这段内存空间,所以为了在函数中将指针参数指向内存空间,那么需要传递指向这个指针的指针。
TreeNode *tree=nullptr;
TreeNode* *p=&tree;
把tree的地址赋给指向TreeNode指针类型的指针。