阐述使用线索二叉树的原因以及如何建立线索二叉树。
时间: 2023-06-07 16:10:53 浏览: 46
使用线索二叉树的主要原因是为了优化二叉树的遍历效率。在普通的二叉树中,进行中序遍历需要使用递归或者栈来实现,而递归和栈都需要消耗额外的空间,并且递归还会增加程序的调用深度。而线索二叉树通过对二叉树的遍历路线进行预处理,把原本为空的左右指针指向前驱和后继节点,使得可以直接从一个节点访问到它的前驱和后继节点,从而省略了递归和栈的使用,提高了遍历效率。
线索化的过程可以分为两步:首先进行一次中序遍历,将遍历路径上的节点的左右指针线索化;然后建立头结点,头结点的左指针指向根节点,右指针指向遍历的最后一个节点。这样,从头结点开始进行中序遍历,就可以依次遍历所有节点。
相关问题
线索二叉树的建立代码c语言
下面是线索二叉树的建立代码(C语言):
```c
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树结点类型
typedef struct TreeNode {
int data;
struct TreeNode *left;
struct TreeNode *right;
int ltag; // 左线索标志
int rtag; // 右线索标志
} TreeNode;
// 全局变量,用来记录上一个访问的结点
TreeNode *pre = NULL;
// 创建二叉树
TreeNode* createTree() {
int val;
scanf("%d", &val);
if (val == -1) {
return NULL;
} else {
TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode));
node->data = val;
node->left = createTree();
node->right = createTree();
node->ltag = 0;
node->rtag = 0;
return node;
}
}
// 中序遍历线索化二叉树
void inOrderTraversal(TreeNode *root) {
TreeNode *p = root;
while (p != NULL) {
while (p->ltag == 0) {
p = p->left;
}
printf("%d ", p->data);
while (p->rtag == 1) {
p = p->right;
printf("%d ", p->data);
}
p = p->right;
}
}
// 中序线索化二叉树
void inOrderThreading(TreeNode *root) {
if (root == NULL) {
return;
}
// 遍历左子树
inOrderThreading(root->left);
// 处理当前结点
if (root->left == NULL) {
root->left = pre;
root->ltag = 1;
}
if (pre != NULL && pre->right == NULL) {
pre->right = root;
pre->rtag = 1;
}
pre = root;
// 遍历右子树
inOrderThreading(root->right);
}
int main() {
// 创建二叉树
printf("请输入二叉树的结点,-1表示空结点:\n");
TreeNode *root = createTree();
// 中序线索化二叉树
inOrderThreading(root);
// 遍历线索化二叉树
printf("中序遍历线索化二叉树:\n");
inOrderTraversal(root);
return 0;
}
```
c语言实现线索二叉树的建立和遍历
线索二叉树是一种特殊的二叉树,它在原有的二叉树上增加了一些指向前驱和后继节点的指针,以实现更加高效的遍历。下面是C语言实现线索二叉树的建立和遍历的示例代码。
首先,定义线索二叉树的节点结构体:
```c
typedef struct ThreadedNode {
int data;
struct ThreadedNode *left;
struct ThreadedNode *right;
int left_tag;
int right_tag;
} ThreadedNode;
```
其中,left_tag和right_tag分别表示该节点的左右指针是否为线索指针,0表示指向子节点,1表示指向前驱或后继。
接下来,定义建立线索二叉树的函数:
```c
ThreadedNode *createThreadedTree(int *arr, int n) {
ThreadedNode *root = NULL;
ThreadedNode **p = &root;
int i = 0;
for (; i < n; i++) {
ThreadedNode *node = (ThreadedNode *) malloc(sizeof(ThreadedNode));
node->data = arr[i];
node->left = NULL;
node->right = NULL;
node->left_tag = 0;
node->right_tag = 0;
*p = node;
p = &(node->right);
}
return root;
}
```
该函数接收一个整型数组和数组长度,返回一个指向根节点的指针。函数通过遍历数组创建二叉树,并将每个节点的右指针设置为下一个节点的指针,以便后续线索化。
接下来,定义线索化函数:
```c
void inorderThreaded(ThreadedNode *root, ThreadedNode **pre) {
if (root == NULL) {
return;
}
inorderThreaded(root->left, pre);
if (root->left == NULL) {
root->left_tag = 1;
root->left = *pre;
}
if (*pre != NULL && (*pre)->right == NULL) {
(*pre)->right_tag = 1;
(*pre)->right = root;
}
*pre = root;
inorderThreaded(root->right, pre);
}
void threaded(ThreadedNode *root) {
ThreadedNode *pre = NULL;
inorderThreaded(root, &pre);
}
```
该函数接收一个指向根节点的指针,将二叉树线索化。通过中序遍历二叉树,并将每个节点的前驱和后继指针设置为前一个和后一个节点,以实现遍历时的跳转。
最后,定义遍历线索二叉树的函数:
```c
void inorderTraverse(ThreadedNode *root) {
ThreadedNode *p = root;
while (p != NULL) {
while (p->left_tag == 0) {
p = p->left;
}
printf("%d ", p->data);
while (p->right_tag == 1) {
p = p->right;
printf("%d ", p->data);
}
p = p->right;
}
}
```
该函数接收一个指向根节点的指针,按中序遍历顺序输出二叉树节点的值。函数先从根节点开始,沿着左子树的线索指针一直往下走,直到找到最左边的节点,输出该节点的值。然后沿着右子树的线索指针往上回溯,输出每个节点的值,直到回到根节点。最后沿着右指针走到右子树,继续进行遍历。
完整代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct ThreadedNode {
int data;
struct ThreadedNode *left;
struct ThreadedNode *right;
int left_tag;
int right_tag;
} ThreadedNode;
ThreadedNode *createThreadedTree(int *arr, int n) {
ThreadedNode *root = NULL;
ThreadedNode **p = &root;
int i = 0;
for (; i < n; i++) {
ThreadedNode *node = (ThreadedNode *) malloc(sizeof(ThreadedNode));
node->data = arr[i];
node->left = NULL;
node->right = NULL;
node->left_tag = 0;
node->right_tag = 0;
*p = node;
p = &(node->right);
}
return root;
}
void inorderThreaded(ThreadedNode *root, ThreadedNode **pre) {
if (root == NULL) {
return;
}
inorderThreaded(root->left, pre);
if (root->left == NULL) {
root->left_tag = 1;
root->left = *pre;
}
if (*pre != NULL && (*pre)->right == NULL) {
(*pre)->right_tag = 1;
(*pre)->right = root;
}
*pre = root;
inorderThreaded(root->right, pre);
}
void threaded(ThreadedNode *root) {
ThreadedNode *pre = NULL;
inorderThreaded(root, &pre);
}
void inorderTraverse(ThreadedNode *root) {
ThreadedNode *p = root;
while (p != NULL) {
while (p->left_tag == 0) {
p = p->left;
}
printf("%d ", p->data);
while (p->right_tag == 1) {
p = p->right;
printf("%d ", p->data);
}
p = p->right;
}
}
void destroyThreadedTree(ThreadedNode *root) {
if (root != NULL) {
destroyThreadedTree(root->left);
destroyThreadedTree(root->right);
free(root);
}
}
int main() {
int arr[] = {5, 3, 7, 2, 4, 6, 8};
int n = sizeof(arr) / sizeof(arr[0]);
ThreadedNode *root = createThreadedTree(arr, n);
threaded(root);
inorderTraverse(root);
destroyThreadedTree(root);
return 0;
}
```