#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;
}