你问的是二叉树吧。首先对于lchild 和 rchild,应该明确它们是指针类型。每一个子树本身也是树。所以lchild和rchild应该是指向BitNode类型的指针,所以加了*。
至于*BiTree,你可以认为 BitNode 等价于*BiTree。那么意思不就是,BiTree所指向的空间内容是BitNode类型的数据。如主函数一开始定义的,BiTree T。此处的T就是指向BitNode的一个指针。说白了程序中凡是用BiTree定义的,都可以用BitNode*来替换。对于初始化函数InitBiTree。他的参数为一个指向BiTree的指针。函数体应该错了吧。应该是*T=NULL;主函数调用该函数时,把主函数用T的地址传递给了形参T。即,实参是&T。想想看,如果我们改变T里面的值(实际上是一个地址),这是我们的初衷吗,T里面的值是用来寻找我们真正要操作的单元的。用*T便指向了我们所要的单元(我指的是函数体内的操作。)。二叉树的一系列函数中,你会发现有的是会改变二叉树本身的结构的。比如初始化,我们让一个新树指向NULL。还有接下来的CreateBiTree。涉及到结点的插入。这也是改变二叉树结构。其中的递归调用CreateBiTree(&((*T)->lchild)); *T的意思是找到T所指的BiTree类型的数据。这个数据才能使用lchild。前面的&就是取lchild的地址。因为函数声明,参数要的是BiTree*。取地址,赋给BiTree* T (T里面放的就是地址)。主函数里面出现的函数叫做调用。前面加&。就是取地址,传递给形参。还有就是一些不改变二叉树的结构的函数。比如PreOrderTraverse(T->lchild);它只是把二叉树的内容输出去。该函数,实参把自己的值赋给形参,之后形参的所有操作都与实参无关。即形参自己开辟了一块空间,空间里的值都是照实参原样复制一遍。然后函数的操作就是在形参这片空间里完成的。也就是说,如果要改变二叉树的结构内容,就要用指针做参数。如果不需要改变,用指针倒显得多余,用普通的值传递就可以了。定义变量时,出现了*,则表示定义了指针。在使用指针变量时,出现*,那也是加在变量前面的。这个是对指针所指的单元进行直接操作。希望对你有所帮助。
1. struct BitNode *lchild, *rchild; 这是定义两个结构体指针,类型为 struct BitNode *, 用于指向其左子结点和右子结点
2. typedef 是将类型重定义,这里是将 struct BitNode 重定义为 BitNode, 将 struct BitNode * 重定义为 BiTree, 那么要后面要定义一个结构体变量,就可以 BitNode node; 要定义结构体变量就可以 BiTree p;
3. int InitBiTree(BiTree *T); 这个参数实际上是一个二级指针,它一般是用于返回的,你一般可以这样调用:BiTree p; InitTree(&p); 如果此函数初始化成功,则p中会存放有效指针
4. int PreOrderTraverse(BiTree T); 这个函数仅仅是使用指针而已,不作返回
5. 第3点已经说明,传指针变量的地址过去,用于返回
后面的再自己推敲一下,其实如果你真正理解 void Swap(int *a, int *b) 的具体实现,从内存的角度去分析,这上面的指针应该是很好理解的。
你想要改变实参的内容,那你就得用&T或*T,若只是计算实参值的结果,那就用T——就这么简单。
typedef struct BitNode
{ElemType data;
struct BitNode *lchild,*rchild; //这儿定义如果不要* 行不行??不行,否则循环定义
}BitNode,*BiTree; //这儿定义如果不要* 行不行?BitNode与*BiTree分别有啥用?
//*BiTree是定义结构体指针简称,BitNode是定义结构体简称
int InitBiTree(BiTree *T);//这儿的*也不太懂
int CreateBiTree(BiTree *T);
int PreOrderTraverse(BiTree T);//为什么这儿又可以不要*?//可以用*,类型变化为指针
int main(){
BiTree T;
InitBiTree(&T);//这儿定义如果不要& 行不行??//以下要不要,关键是必须和函数参数类型匹配
printf("请输入先序构造:\n");
CreateBiTree(&T);
printf("先序输出如下\n");
PreOrderTraverse(T);//为什么这儿又可以不要&?
return OK;
}
int InitBiTree(BiTree *T){ //这儿定义如果不要* 行不行??
//这肯定不行,可以用引用代替,因为目的是初始化一个列表,如果不用*,初始化的是临时变量
T=NULL;
return OK;
}
int CreateBiTree(BiTree *T){
ElemType ch;
scanf_s("%c",&ch);
if(ch=='#') *T=NULL;
else {
if (!(*T = (BitNode *)malloc(sizeof(BitNode)))) exit(-1);
(*T)->data = ch;
CreateBiTree(&((*T)->lchild)); //这儿定义如果不要*&行不行??
CreateBiTree(&((*T)->rchild));
}
return OK;
}