二叉树这边理解两个问题,一个问题是递归,第一个问题是二级指针。
1.二叉树的创建:
创建二叉树的时候,输入参数的指向二叉树根结点的指针的地址。为什么要这么做?通过创建函数来理解:
- 假设传入的是指向结点的指针:
调用创建函数代码:
BiTree T1;
T1 = NULL;
CreateBiTree(T1);
此时的创建函数如下:
void CreateBiTree(BiTree T)
{
TElemType ch;
ch = str[index++];
if(ch=='#')
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiTNode));
if(!T)
exit(OVERFLOW);
(T)->data = ch;
CreateBiTree(&(T)->lchild);
CreateBiTree(&(T)->rchild);
}
}
此时出现的情况是:在CreateBiTree中创建实参T1的拷贝T,通过malloc开辟空间,将T指向malloc开辟的空间,但是在CreateBiTree函数调用完后,也就是在二叉树创建完成后,此时T将消失,此时原先的实参T1依旧为空,也就是二叉树创建不成功。
- 传入的是指向二叉树根结点的指针的地址:
BiTree T1;
T1 = NULL;
CreateBiTree(&T1);
创建函数:
void CreateBiTree(BiTree *T)
{
TElemType ch;
ch = str[index++];
if(ch=='#')
*T = NULL;
else
{
*T = (BiTree)malloc(sizeof(BiTNode));
if(!*T)
exit(OVERFLOW);
(*T)->data = ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
此时形参指针T里面存放的是实参T1的地址,而对*T操作其实就相当于对实参T1直接操作,在函数CreateBiTree执行完后,释放形参指针T不会影响已经创建的二叉树。如下图所示:
看一个最常见的交换函数的例子:
int m,n;
m = 1;
n = 4;
swap(m,n);
printf("m= %d\n",m);
printf("n= %d\n",n);
交换函数,想在交换函数中将m,n交换值:
void swap(int i,int j)
{
int temp = i;
i = j;
j = temp;
}
指向过程如下图所示:实参m=1,n=4传递该形参i,j,在swap函数中执行交换,交换过后,i=4,j=1,在函数swap执行完后,变量i,j被释放了,但此时m和n的值并未改变。
因为单向传送的值传递方式,形参值不能使实参的值随之改变。
采用办法,改传递实参的地址:
swap(&m,&n);
void swap(int *p1,int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
此时,执行过程如下图:
形参指针p1和指针p2接收m和n的地址,此时对*p1操作就相当于对m操作,对*p2操作就相当于对n操作,在函数swap执行完后,指针p1和p2被释放,此时m和n中的值已经完成了交换。
2.单链表的删除
单链表的删除送入指针就可以