昨天寫了個二叉樹遍歷,自以為對二叉樹很了解了。自大的認為線索二叉樹不過是加了點線索而已,不足掛齒。可是當真的自己編程序寫的時候才發現完全不是那么容易。在有線索的情況下,如何判別Link類型的下一節點,如何不用棧跳過已訪問節點搞得腦子暈暈的。 折騰一個晚上,才根據書上把線索二叉樹的建立、中序遍歷給寫出來。要回去繼續好好的理清關系。
#include <stdio.h> #include <stdlib.h> typedef enum PointerTag{Link, Thread}; typedef struct BiThrNode { int data; struct BiThrNode *lchild, *rchild; PointerTag LTag, RTag; }BiThrNode, *BiThrTree; int createBinaryTree(BiThrTree &T) //線索二叉樹建立 { int ch; scanf("%d", &ch); if(ch != 0) { T = (BiThrTree)malloc(sizeof(BiThrNode)); T->data = ch; createBinaryTree(T->lchild); createBinaryTree(T->rchild); } else { T = NULL; } return 0; } int InTreading(BiThrTree T, BiThrTree &pre) //中序線索建立 內 { if(T != NULL) { InTreading(T->lchild, pre); if(T->lchild == NULL){ T->LTag = Thread; T->lchild = pre;} else{ T->LTag = Link;} if(pre->rchild == NULL){ pre->RTag = Thread; pre->rchild = T;} else{ T->RTag = Link;} pre = T; InTreading(T->rchild, pre); } return 0; } int InOrderThreading(BiThrTree & Thrt, BiThrTree T) //中序線索建立 外 { BiThrTree pre; Thrt= (BiThrTree)malloc(sizeof(BiThrNode)); Thrt->LTag = Link; Thrt->RTag = Thread; Thrt->rchild = Thrt; if(T == NULL) Thrt->lchild = Thrt; else { Thrt->lchild = T; pre = Thrt; InTreading(T, pre); pre->rchild = Thrt; pre->RTag = Thread; Thrt->rchild = pre; } return 0; } int visit(int data) { printf("%d ", data); return 0; } int InOrderTraverse_Thr(BiThrTree T) //中序非遞歸線索二叉樹遍歷 { BiThrTree p = T->lchild; while(p != T) { while(p->LTag == Link) p = p->lchild; visit(p->data); while(p->RTag == Thread && p->rchild != T) { p = p->rchild; visit(p->data); } p = p->rchild; } return 0; } int main() { BiThrNode TT; BiThrTree T, Thrt; createBinaryTree(T); InOrderThreading(Thrt, T); InOrderTraverse_Thr(Thrt); //注意遍歷的時候要帶上頭結點 return 0; }