二叉线索树-创建中序二叉线索树、查找前驱、查找后继、按照前驱或后继遍历
#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; }