在說明之前,先來看一個栗子:
1 //前略 2 typedef struct Node { 3 int data; 4 struct Node *lchild, *rchild; 5 } *BiTree; 6 void CreateBiTree (BiTree *T) 7 { 8 char ch; 9 scanf("%c", &ch); 10 if (ch == '#') 11 *T = NULL; 12 else 13 { 14 *T = (BiTree)malloc(sizeof(Node)); //分配空間 15 if (!*T) //如果分配失敗 16 exit(OVERFLOW); //內存溢出 17 (*T)->data = ch; 18 CreateBiTree(&(*T)->lchild); //用(*T)->lchild作為新的T,下同 19 CreateBiTree(&(*T)->rchild); 20 } 21 }
這是一個二叉鏈表的實現,(#表示空樹)CreateBiTree的參數是BiTree *T,也就是struct Node ** T,那么,為什么要用這個二級指針參數呢?直接BiTree T不好嗎?
當然不行(-- _ --),回想一下,就跟變量一樣,當你要在一個函數中修改主函數的變量時,需要用到指向這個變量的指針,這樣子才能真正的修改變量,而同樣的,在二叉鏈表里面,我們需要修改的就是結構指針(的指向),以此來實現鏈表,因此,我們需要一個二級結構指針,來修改結構指針的指向。
那么這里有一個誤區,有人認為,自己一開始修改的是T,然后是T->lchild和T->rchild, 再然后是T->lchild->lchild ..... ... ,其實不然,你一直都在修改T,每當一個T修改完成,就會把下一個地址(比方說T->lchild) 重新作為T,然后繼續修改。
以上。
PS:如果有點懵的話,這里有一個簡單的理解方法,那就是你把一級指針看成節點,二級指針看成一級指針,這樣子,如果我們要修改節點(A)地址區指向的下一個節點(B),那么就要修改這個原本指向NULL的指針(一級),再然后更新一波指針,即把原來存在於(A)而指向於(B)的指針又變成NULL(原來從A指向B的指針當然存在,只是你這時候無法通過當前指針訪問到而已)。