在二叉树中,有很多节点的指针域为空域,造成结点的浪费。针对这种现象,提出线索化二叉树这一概念,其基本思想是遵从中序遍历二叉树,将二叉树的空节点有效的利用起来。具体来说,是按照以下的步骤来实现的。
本文是利用中序遍历的思想对二叉树进行一个线索化:已知一颗二叉树如图所示:
如图1,是一颗普通的二叉树,一个节点有左右孩子和数据域。现在我们知道这个二叉树的中序遍历结果,如图2所示,然后按照中序遍历的结果,将这个二叉树线索化。
根据图2,我们能够清楚的看清每一个结点的前驱,每个结点的后继。而线索化二叉树所做的工作就是,将每一个结点的左孩子指向该结点的前驱,将每个结点的右孩子指向该结点的后继。那么,现在的工作就是具体来实现这个过程。首先,一个线索化二叉树的结点的数据结构是这个样子的:
typedef int ElemType;
typedef enum{LINK=0,THREAD=1} Tag;
typedef struct BiNode
{
BiNode *left;
BiNode *right;
ElemType data;
Tag taglef, tagright;
}BiNode, *BiTree;然后,按照中序遍历的过程,找到最左边的孩子结点p,令p的左孩子指向一个提前定义的全局变量,并且,修改p的做孩子标志,表示已将其线索化。并且将pre修改为p,p指向p中序遍历的下一个。其中p的遍历顺序为DBGEHACF,pre永远为p的前一个。
按照图3,图4,一直到图5的顺序,实现了所有结点,除了最后一个结点的线索化,最后,再对最后一个结点进行一个线索化,二叉树中序线索化就完成了。以下是具体的实现代码,以及最终的实现界面:
#include<iostream>
using namespace std;
typedef int ElemType;
typedef enum{LINK=0,THREAD=1} Tag;
typedef struct BiNode
{
BiNode *left;
BiNode *right;
ElemType data;
Tag taglef, tagright;
}BiNode, *BiTree;
BiNode* BuyNode(ElemType dat)
{
BiNode* newnode = new BiNode[1];
newnode->data = dat;
newnode->left = NULL;
newnode->right = NULL;
newnode->taglef = LINK;
newnode->tagright = LINK;
return newnode;
}
BiNode* CreatePreorder(ElemType* &p)
{
BiNode* root = NULL;
if (*p < 0 )
{
return root;
}
else
{
root = BuyNode(*p);
if (root == NULL) return NULL;
root->left = CreatePreorder(++p);
root->right = CreatePreorder(++p);
return root;
}
}
void Inorder(BiNode* root)
{
if (root)
{
Inorder(root->left);
cout << root->data << " ";
Inorder(root->right);
}
}
void Preorder(BiNode* root)
{
if (root)
{
cout << root->data << " ";
Preorder(root->left);
Preorder(root->right);
}
}
void Pastorder(BiNode* root)
{
if (root)
{
Pastorder(root->left);
Pastorder(root->right);
cout << root->data << " ";
}
}
void transform(BiNode* root, BiNode* &pre)
{
if (root)
{
transform(root->left, pre);
if (root->left == NULL)
{
root->left = pre;
root->taglef = THREAD;
}
if (pre->right == NULL)
{
pre->right = root;
pre -> tagright = THREAD;
}
pre = root;
transform(root->right, pre);
}
}
void ThreadBiTree(BiNode* root)
{
if (root == NULL) return ;
BiNode* pre =BuyNode(-1);
transform(root, pre);
BiNode* temp = root;
while (temp->right != NULL)
{
temp = temp->right;
}
temp->tagright = THREAD;
temp->right =NULL;
}
void InOrderThr(BiNode* root)
{
if (root == NULL) return;
BiNode* first = root;
while (first->right!=NULL)
{
while (first->taglef != THREAD)
{
first = first->left;
}
cout << first->data << " ";
while (first->tagright == THREAD)
{
first = first->right;
cout << first->data << " ";
}
first = first->right;
}
cout << first->data << endl;
}
void main()
{
int arr[] = { 12, 23, 45,-1,-1, 56, 67,-1,-1, 78, -1,-1,34,-1,89,-1,-1 };
int len = sizeof(arr) / sizeof(arr[0]);
BiTree root = NULL;
int *p = arr;
root = CreatePreorder(p);
cout << "中序遍历二叉树"<<endl;
Inorder(root);
cout << endl;
cout << "先序遍历二叉树" << endl;
Preorder(root);
cout << endl;
cout << "后序遍历二叉树" << endl;
Pastorder(root);
ThreadBiTree(root);
cout << endl;
cout << "中序遍历线索化二叉树" << endl;
InOrderThr(root);
}
1492

被折叠的 条评论
为什么被折叠?



