#include <iostream> #include <stack> using namespace std; struct BiThrNode { int data; BiThrNode *left; BiThrNode *right; bool ltag;//0表示left指向左子,1表示left指向直接前驅 bool rtag; //BiThrNode(int val,BiThrNode *l,BiThrNode *r,bool lt,bool rt):data(val),left(l),right(r),ltag(lt),rtag(rt){} }; /*遞歸 建立二叉查找/搜索樹*/ BiThrNode *CreateTree(BiThrNode *root, int val) { if(!root) { root = (BiThrNode *)malloc(sizeof(BiThrNode)); root->data = val; root->left = nullptr; root->right = nullptr; root->ltag = 0; root->rtag = 0; } if (val < root->data) root->left = CreateTree(root->left, val); if (val > root->data) root->right = CreateTree(root->right, val); return root; } /*普通中序遍歷*/ void inorder(BiThrNode *root) { if (!root) return; stack<BiThrNode *> s; BiThrNode *curr = root; while (curr || !s.empty()) { if (curr) { s.push(curr); curr = curr->left; } else { cout << s.top()->data << " "; curr = s.top()->right; s.pop(); } } } /* 1、創建中序二叉線索樹 */ BiThrNode *pre; //全局變量指向線索二叉樹的前驅節點,第一個前驅是head void intreading(BiThrNode *node) {//除中間部分,就是遞歸中序遍歷算法。這里把pre和node看做雙向鏈表節點 if (node) { intreading(node->left); if (!node->left) { node->ltag = 1; node->left = pre; } if (!pre->right) { pre->rtag = 1; pre->right = node; } pre = node; intreading(node->right); } } void inCreateBitree(BiThrNode *&head, BiThrNode *root) {//構建頭節點,左子指向二叉搜索樹頭節點,右子指向樹最右子 if (!root) return; head->ltag = 0;//調整頭結點的左子 head->left = root; head->rtag = 1;//調整頭結點的左子 head->right = head;//回指,經過intreading后才置為樹最右子 pre = head;//用於intreading intreading(root);//中序遍歷線索化樹,只差線索樹最后一個節點和head關系 pre->rtag = 1;//調節頭結點右子 pre->right = head; head->right = pre; } /* 2、中序二叉線索樹 查找某節點前驅 【二叉查找樹尋找前驅做對比】 */ BiThrNode *inBiSearchPre(BiThrNode *node) { BiThrNode *pre; pre = node->left; if (node->ltag != 1)//左子不是前驅 { while (pre->rtag == 0)//找第一個沒有右子的節點 pre = pre->right; } return pre; } /* 3、中序二叉線索樹 查找某節點后繼 */ BiThrNode *inBiSearchPost(BiThrNode *node) { BiThrNode *post; post = node->right; if (node->rtag != 1)//右子不是前驅 { while (post->ltag == 0)//找第一個沒有左子的節點 post = post->left; } return post; } /* 4、根據前驅節點進行中序線索二叉樹的遍歷(倒序) */ void InOrderPre(BiThrNode *head) { BiThrNode *p; p = head->right;//中序線索二叉樹的最右子節點 while (p != NULL && p != head)//like鏈表,根據線索遍歷 { cout << p->data << " "; p = inBiSearchPre(p);//根據線索,找到p的后繼節點 } } /* 5、根據后繼節點進行中序線索二叉樹的遍歷(正序) */ void InOrderPost(BiThrNode *head) { BiThrNode *p; p = head->left; while (p->ltag != 1)//從二叉線索樹頭找到最左子 { p = p->left; } while (p != NULL && p != head)//like鏈表,根據線索遍歷 { cout << p->data << " "; p = inBiSearchPost(p);//根據線索,找到p的后繼節點 } } int main() { int t[] = { 4,2,5,1,3,6,7 }; BiThrNode *root = nullptr; for (int i = 0; i < 7; i++) root = CreateTree(root, t[i]); cout << "中序遍歷二叉查找樹:"; inorder(root); cout<< endl; BiThrNode *head = new BiThrNode;//二叉線索樹頭結點,指向樹根 inCreateBitree(head, root);//創建中序線索二叉樹 cout << "根據后繼節點進行中序線索二叉樹的遍歷(正序):"; InOrderPost(head); cout << endl; cout << "根據前驅節點進行中序線索二叉樹的遍歷(倒序):"; InOrderPre(head); cout << endl; }