线索二叉树

数据定义:

 1 /*

 2  * 枚举类型定义     NO -> 没有线索化    YES -> 线索化了的

 3  */

 4 enum Thread { NO, YES }

 5 

 6 /*

 7  * 线索二叉树的结点类型定义

 8  */

 9 struct Node

10 {

11     ElementType data;                   // 数据域

12     Thread leftTag;                     // 左指针标志域

13     Thread rightTag;                    // 右指针标志域

14     struct Node *leftChild;             // 左指针域

15     struct Node *rightChild;            // 右指针域

16 };

为二叉树加序:

 1 /*

 2  * 为二叉树加前序线索   递归实现

 3  */

 4 void PreorderThread(Node *root)

 5 {

 6     static Node *prev = NULL;                               /* 指向当前结点的后序前件,用以记忆刚访问过的结点 */

 7     if(root != NULL) {                                      // 若二叉树为空,结束递归

 8         if(prev != NULL && prev->rightTag = YES)            // 若当前结点的前序前件需要加线索

 9             prev->rightChild = root;                        // 对当前结点的前序前件加指向后件(当前结点)的线索

10         if(root->leftChild == NULL) {                       // 若当前结点的左指针为空

11             root->leftTag = YES;                            // 将其修改为指向前件的线索

12             root->leftChild = prev; 

13         }   

14         if(root->rightChild == NULL)                        // 若当前结点的右指针域为空,修改右指针标志

15             root->rightTag = YES;   

16         prev = root;                                        // 将当前结点置为前件,后件将成为当前结点

17     

18         PreorderThread(root->leftChild);                    // 递归对左子树加前序线索

19         PreorderThread(root->rightChild);                   // 递归对右子树加前序线索

20     }

21 }

22 

23 /*

24  * 为二叉树加中序线索   递归实现

25  */

26 void InorderThread(Node *root)

27 {

28     static Node *prev = NULL;                               /* 指向当前结点的后序前件,用以记忆刚访问过的结点 */

29     if(root != NULL) {                                      // 若二叉树为空,结束递归

30         InorderThread(root->leftChild);                     /* 递归对左子树加中序线索 */

31     

32         if(prev != NULL && root->rightTag == YES)           // 若当前结点的中序前件需要加线索

33             prev->rightChild = root;                        // 对当前结点的中序前件加指向后件(当前结点)的线索

34         if(root->leftChild == NULL) {                       // 若当前结点的左指针为空

35             root->leftTag = YES;                            // 将其修改为指向前件的线索

36             root->leftChild = prev;     

37         }

38         if(root->rightChild == NULL)                        // 若当前结点的右指针域为空,修改右指针标志

39             root->rightTag = YES;

40         prev = root;                                        // 将当前结点置为前件,后件将成为当前结点

41 

42         InorderThread(root->rightChild);                    /* 递归对右子树加中序线索 */

43     }

44 }

45 

46 /*

47  * 为二叉树加后序线索   递归实现 */

48 void PostorderThread(Node *root)

49 {    

50     static Node *prev = NULL;                               /* 指向当前结点的后序前件,用以记忆刚访问过的结点 */

51     if(root != NULL) {                                      // 若二叉树为空,结束递归

52         PostorderThread(root->leftChild);                   // 递归对左子树后序线索化

53         PostorderThread(root->rightChild);                  // 递归对右子树后序线索化

54 

55         if(prev != NULL && root->rightTag == YES)           // 若当前结点的后序前件需要加线索

56             prev->rightChild = root;                        // 对当前结点的后序前件加指向后件(当前结点)的线索

57         if(rot->leftChild == NULL) {                        // 若当前结点的左指针为空

58             root->leftTag = YES;                            // 将其修改为指向前件的线索

59             root->rightChild = prev;

60         }

61         if(root->rightChild == NULL)                        // 若当前结点的右指针域为空,修改右指针标志

62             root->rightTag = YES;

63         prev = root;                                        // 将当前结点置为前件,后件将成为当前结点

64     }

65 }

利用加序的二叉树遍历:

 1 /*

 2  * 利用   前序线索树   遍历二叉树

 3  */

 4 void preorderThreadTreeTraversal(Node *root)

 5 {

 6     Node *currentNode = root;

 7     if(currentNode != NULL) {

 8         while(currentNode != NULL) {

 9             cout << currentNode->data;

10             if(currentNode->leftTag == NO)                      // 当前结点有左孩子,则使其左孩子变为当前结点

11                 currentNode = currentNode->leftChild;

12             else                                                // 若当前结点没有左孩子,则currentNode指向当前结点的前序后件

13                 currentNode = currentNode->rightChild;

14         }

15     }

16 }

17 

18 /*

19  * 利用   中序线索树   遍历二叉树

20  */

21 void inorderThreadTreeTraversal(Node *root)

22 {

23     Node *currentNode = root;                                   // 设定currentNode初始指向中序线索二叉树的根结点

24     if(currentNode != NULL) {                                   // 二叉树为空,结束遍历

25         while(currentNode->leftTag == NO)                       // 找到中序遍历的第一个结点

26             currentNode = currentNode->leftChild;

27         do {                                              /* 依次找出每个结点的后件,直到输出中序线索二叉树的最右边一个结点 */

28             cout << currentNode->data;                          /* 输出当前结点数据 */

29             if(currentNode->rightTag == YES)                    // 若当前结点的右指针是线索,其指示为中序后件

30                 currentNode = currentNode->rightNode;

31             else {                                              /* 若当前结点的右指针指向右孩子 */

32                 currentNode = currentNode->rightChild;          // 从右孩子结点出发找中序后件

33                 while(currentNode->leftTag == NO)               // 找到右子树的最左边一个结点,即为中序后件

34                     currentNode = currentNode->leftChild;

35             }

36         } while(currentNode != NULL); 

37     }

38 }

39 

40 /*

41  * 利用   后序线索树   遍历二叉树

42  */

43 void postorderThreadTreeTraversal( Node *root)

44 {

45     

46 }

 

OK哒!O(∩_∩)O哈哈~

你可能感兴趣的:(二叉树)