標籤:style blog color os 資料 re
資料定義:
1 /* 2 * 枚舉類型定義 NO -> 沒有線索化 YES -> 線索化了的 3 */ 4 enum Thread { NO, YES } 5 6 /* 7 * 線索二叉樹的結點類型定義 8 */ 9 struct Node10 {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哈哈~