我觉得二叉树的构造是最难理解的,其他的还好说。先说说我对构造二叉树的理解吧。从某种角度来说,二叉树也是一种单链表,上一个结点记录下一个结点的地址。他们的区别就在于二叉树的上一个结点可能记录多个下一结点的地址(最多2个),而单链表是只记录一个。
单链表是这样定义的: 二叉树是这样定义的:
struct Node struct Node
{ {
int data; int data;
Node *next; Node *lchild;
}; Node *rchild;
};
单链表是这样构造的(没写数据的存储): 二叉树是这样构造的(我在网上看的代码):
void Create(Node *head) int Create(Node **tp)
{ {
Node *temp_1 = new Node; int x;
head->next = temp_1; scanf("%d",&x);
if(x<0)*tp=NULL,return 0;
Node *temp_2 = new Node; *tp=(Node*)malloc(sizeof(Node));
temp_1->next = temp_2; if(tp==NULL) return 0;
(*tp)->data=x;
Node *temp_3 = new Node; Create(&((*tp)->left));
temp_2->next = temp_3; Create(&((*tp)->right));
} return 0;
}
我的疑问就出在这里:
单链表在构造的时候,是每次动态生成一个新的结点,然后让上一个结点记录它的地址。这个新的结点是在函数里面另外定义的一个变量来存储的,不是直接这样的:void Create(Node *head)//这个代码在小故事会用到。
{
head = new Node;
head->next = temp_1;
Node *temp_2 = new Node;
temp_1->next = temp_2;
Node *temp_3 = new Node;
temp_2->next = temp_3;
}
我想说的是:
那个新生成的结点和那个函数的参数不是同一个变量,为什么二叉树却是啊???并且二叉树的那个构造函数的参数怎么不是指针,怎么是用指针的指针???独白:我明白二叉树在构造的时候,用了递归,也就是说,在每次递归的时候,虽然构造函数的那个参数都是Node **tp,但是,那个构造函数的参数的值都发生了改变。
- 如果单链表真的这样写(上面注释的代码),其实也可以吧。只不过这样就改变了头指针,就是说,如果原本是用一个头指针指向第一个元素,那么现在的情况就是:第一个元素和头指针都是同一个。
- 不管是不是有头指针的单链表,这样写了之后,就是一个不含头指针的单链表,原因就在于第一次的动态生成新结点,改变了head的值。
解答:
之所以用二级指针,是因为要用到一级指针的值,就是要改变指针的内容,相信写过交换2个变量的函数吧,如果不用指针,是交换不了了,因为函数传递的是数值,并没有改变mian函数中变量的值,所以要用一级指针,从某种角度来说,不管是不是用指针,函数传递的都是值,也就是说,它是实参的一个副本,我们用指针之所以能改变其内容(能影响在mian中的值),是改变了其所在的空间中的值,就是地址中的数值。下面写了一个交换2个变量的函数,其思想是交换2个指针所指向的内容;
#include <iostream>
using namespace std;
void swap_(int **x, int**y)
{
int *temp = *x;
*x = *y;
*y = temp;
}
int main(void)
{
int a = 7, b = 3;
int *pa = &a, *pb = &b;
cout<<*pa<<" "<<*pb<<endl;
cout<< pa<<" "<< pb<<endl;
swap_(&pa, &pb);
cout<<*pa<<" "<<*pb<<endl;
cout<< pa<<" "<< pb<<endl;
return 0;
}