C語言線索二叉樹的實現
線索二叉樹的主要操作,包含:以p為根節點的子樹中序線索化,帶頭結點的二叉樹中序線索化和遍歷線索二叉樹這幾個函式。
下面講一下實現程式碼:
首先,依然是型別定義,並宣告一個全域性變數pre:
typedef char ElemType;
typedef struct BiThrNode{
ElemType data;
BiThrNode *lchild, *rchild;
int LTag, RTag;
}BiThrNode,*BiThrTree;
BiThrTree pre;
帶頭結點的二叉樹中序線索化:
BiThrNode *InOrderThreading(BiThrTree T) { BiThrTree Thrt, p; Thrt = (BiThrNode *)malloc(sizeof(BiThrNode)); Thrt->LTag = 0; Thrt->RTag = 1; Thrt->rchild = Thrt; if (!T) Thrt->lchild = Thrt; else { Thrt->lchild = T; pre = Thrt; InThreading(T); Thrt->rchild = pre; pre->RTag = 1; pre->rchild = Thrt; } return Thrt; }
先為Thrt動態分配空間,並讓Thrt->LTag=0,Thrt->Rtag=1,讓Thrt的右子樹指向自己。判斷二叉樹T是否為空樹,如果為空樹,則讓Thrt的左子樹也指向自己;否則,讓其左子樹指向T的根節點,並且讓全域性變數pre=Thrt,線索化T(利用InThreading(),下面會提供程式碼)。注意線索化之後Thrt的右子樹指向的是二叉樹T最左端的節點,pre指向的是T最右端的節點且pre的RTag尚未賦值,pre的rchild並未指向任何位置。所以讓Thrt的右子樹指向pre節點,讓pre->Rtag=1,pre的右節點指向Thrt.最後返回Thrt的值作為樹的頭節點。
以p為根節點的子樹中序線索化:
void InThreading(BiThrTree p)
{
if (p)
{
InThreading(p->lchild);
if (!p->lchild)
{
p->LTag = 1;
p->rchild = pre;
}
else
p->LTag = 0;
if (!pre->rchild)
{
pre->RTag = 1;
pre->rchild = p;
}
else
pre->RTag = 0;
pre = p;
InThreading(p->rchild);
}
}
先判斷p子樹是否為空,如果不為空,利用遞迴對p的左子樹進行線索化。如果p的左子樹為空,則讓p->LTag為1,表示指向p的前驅,並且讓pre賦值給p的右子樹;如果不為空,則讓p->LTag為0,表示指向p的後繼。對pre進行同理操作。最後讓pre移動到p的位置,並利用遞迴對p的右子樹進行線索化。
遍歷線索二叉樹:
void InOrderTraverse_Thr(BiThrTree T)
{
BiThrTree p;
p = T->lchild;
while (p != T)
{
while (p->LTag == 0)
p = p->lchild;
printf("%c", p->data);
while (p->RTag == 1 && p->rchild != T)
{
p = p->rchild;
printf("%c", p->data);
}
p = p->rchild;
}
printf("\n");
}
先宣告一個指標p,讓p指向T的左子樹。當p不為T的時候,則執行以下迴圈:當p->LTag等於0的時候,表示p的左子樹不為空,則一直迴圈讓p指向p的左子樹,讓p到達T最左端的葉子。輸出p的data資料。然後當p->Rtag等於1並且p的右子樹不等於T的時候表示p有後繼並p的右子樹指向其後繼,此時讓p移動到p的右子樹的位置,輸出p的data資料。讓p移動到p的右子樹位置。自此最外的迴圈結束。
建立新二叉樹
BiThrNode *CreateBiTree(BiThrTree T)
{
ElemType ch;
scanf("%c", &ch);
if (ch == '#')
T = NULL;
else
{
T = (BiThrNode *)malloc(sizeof(BiThrNode));
T->data = ch;
T->lchild = CreateBiTree(T->lchild);
T->rchild = CreateBiTree(T->rchild);
}
return T;
}
加入main()測試:
int main(void)
{
BiThrTree T;
int n;
T = NULL;
printf("1.建立二叉樹\n2.轉換為邏輯樹\n3.遍歷二叉樹(按邏輯結構)\n");
while (1)
{
printf("請選擇:");
scanf("%d", &n);
fflush(stdin);
switch (n)
{
case 1:
T = CreateBiTree(T);
break;
case 2:
T = InOrderThreading(T);
break;
case 3:
InOrderTraverse_Thr(T);
}
}
return 0;
}