线索二叉树利用二叉树空余的指针域,来实现二叉树的链式化。然后,就可以通过前驱,后继像双向链表一样根据某种遍历次序对树的结点进行访问。
数据结构:
1 struct node{ 2 int data; 3 struct node* left,*right; 4 int ltag,rtag; //=0时,表明指向子结点;=1时,表示指向前驱/后继 5 }
建立线索二叉树:
- 不同的遍历顺序,会得到不同的线索二叉树。
- 一般使第线索链表的头和尾指向NULL(也可以加入一个头指针)
以中序遍历为例:(对左子树处理,对该结点处理,对右子树处理)
1 // p:当前结点,pre:前驱结点 ; 对每一个点进行处理(NULL,ltag=0,ltag=1) 2 void CreateNode(node &p,node& pre){ 3 if(p!=NULL){ 4 CreateNode(p->left,pre); // pre进行递归改变!!! 对左子树进行处理 5 // 左子树为空 6 if(p->left==NULL){ 7 p->left=pre; 8 p->ltag=1; 9 } 10 // 建立前驱结点的后继线索 11 if(pre!=NULL && pre->right!=NULL){ 12 pre->right=p; 13 pre->rtag=1; 14 } 15 pre=p; 16 CreateNode(p->right,pre); // 对右子树处理 17 } 18 } 19 // 建树 20 void CreateTree(node* root){ 21 node* pre=NULL; 22 if(root!=NULL){ 23 CreateNode(root,pre); 24 pre->right=NULL; // 遍历最后结点 25 pre->rtag=1; 26 } 27 }
线索二叉树的遍历:
- 需要找到线索链表的头结点,在中序和后序遍历中,头结点为最左结点;在先序遍历中,头结点为根结点;
- 然后就可以根据rtag的值来访问整个序列。
以中序为例:
1 // 寻找中序遍历第一个结点 2 node* FirstNode(node* root){ 3 while(root->left!=NULL){ 4 root=root->left; 5 } 6 return root; 7 } 8 9 // 获得该结点的下一个结点 10 node* GetNextNode(node* p){ 11 if(p->rtag==0){ 12 return FirstNode(p->right); // 对于有右子树的根结点而言,后面第一个结点是右子树的最左结点 13 } 14 else{ 15 return p->right; 16 } 17 } 18 19 // 中序遍历 20 void Inorder(node* root){ 21 for(node* p=FirstNode(root);p!=NULL;p=GetNextNode(p)){ 22 ; // 处理 23 } 24 }
原文地址:https://www.cnblogs.com/yy-1046741080/p/11511263.html
时间: 2024-11-13 11:00:15