复习了一下二叉树的知识,想用C++实现一颗二叉树,没想到竟然在创建二叉树时忽略了点东西。
本来的惯性思维是:用指针做参数传递时,指针指向的值会被同步改变。
于是调用创建树的方法时,只是传递了空的指针,然后在函数中为指针开辟空间,递归创建二叉树。 然后遍历二叉树时发现二叉树为空。这是为什么呢?
上面惯性思维所想的的确没有错,它是对的;那为什么创建的树为空呢?那是因为,我们在创建树时,在创建方法中改变的不仅是指针指向的值,还有指针本身的值
错误的创建代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
void CreatTree(BiTree*p)
{
char ch;
cin >> ch;
if (ch == '#')
p = NULL;
else {
p = new BiTree();
p->value = ch;
CreatTree(p->lift);
CreatTree(p->right);
}
}

在上述代码中,当使用new关键字开辟空间后(new关键在在自由储存区申请一快内存,它返回一个指向这块内存的指针),我们又改变了这个指针指向的值;因此,在这里指针本身和指针指向的值都发生了改变。因此,当我们创建二叉树时,应该使用指针的引用或者二级指针。示例代码如下:

  • 堆是操作系统维护的一块内存,而自由存储是C++中通过new与delete动态分配和释放对象的抽象概念。堆与自由存储区并不等价。我们可以重载new关键字改用其他内存作为自由储存区。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//使用二级指针做参数
void CreatTree(BiTree**p)
{
char ch;
cin >> ch;
if (ch == '#')
*p = NULL;
else {
*p = new BiTree();
(*p)->value = ch;
CreatTree(&(*p)->lift);
CreatTree(&(*p)->right);
}
}

//使用指针的引用做参数
void CreatTree(BiTree* &p)
{
char ch;
cin >> ch;
if (ch == '#')
p = NULL;
else {
p = new BiTree();
p->value = ch;
CreatTree(p->lift);
CreatTree(p->right);
}
}

 评论