线索化的二叉树为:
二叉树线索化的目的:
1.二叉树的线索化的目的是为了快速找到遍历顺序中某个结点的前驱或者后继。
2.二叉树线索化可以实现从某个结点开始遍历二叉树,而不用局限于只能从头结点进行遍历
3.所以二叉树的线索化与遍历序列有关,因为二叉树的遍历序列有三种,所以二叉树的线索化也有三种
a.二叉树的先序线索化
b.二叉树的中序线索化
c. 二叉树的后序线索化
4.二叉树的线索化说白了就是把那n+1个空指针利用起来,指向其前驱或者指向其后继。
代码实现:
注释很详细,不再做过多的解释,复制粘贴至C++编译器可直接运行。
#include<stdio.h>
#include<stdlib.h>
#define ElemType int
#define null NULL
/*
1.二叉树是一个有序树,左子树、右子树不可颠倒
2.二叉树的分类:
满二叉树 : 高度为h,含有2^h-1个结点的二叉树
完全二叉树 : 在满二叉树的基础上,可去掉诺干个编号更大的结点
二叉排序树 : 左子树关键字<根节点关键字<右子树关键字
平衡二叉树 : 左右子树深度差不超过1 (平衡二叉树依然是个二叉排序树) --> 平衡二叉树具有更高的搜索效率
平衡二叉树就是在限制树在生长的时候,尽量横着生长,这样我们在根节点搜索的时候,就可以减少比较次数。
3.二叉树的存储结构:(在内存中以什么组织方式存在)
1、顺序存储(用数组实现)。
顺序存储只适用于完全二叉树,即只有完全二叉树才可以使用顺序表存储。
如果我们想顺序存储普通二叉树,需要提前将普通二叉树转为完全二叉树。
2、链式存储(用链表实现)。
哪种形态的二叉树都适合存储。
4.二叉树的遍历(4种遍历方法) 这四种遍历方式均可以采用递归和非递归的方式实现。
1.层次遍历 需要借助队列辅助,由于不知道二叉树的元素个数,所以我们使用链队列比较合适
2.先序遍历 空间复杂度O(h) h为二叉树的高度
3.中序遍历
4.后续遍历
5. 由遍历序列反推二叉树 (必须要有中序序列才行)
1.前序+中序 可以反推出唯一的二叉树
2.后序+中序 可以反推出唯一的二叉树
3.层次+中序 可以反推出唯一的二叉树
6.二叉树的线索化
1.二叉树的线索化的目的是为了快速找到遍历顺序中某个结点的前驱或者后继。
2.二叉树线索化可以实现从某个结点开始遍历二叉树,而不用局限于只能从头结点进行遍历
3.所以二叉树的线索化与遍历序列有关,因为二叉树的遍历序列有三种,所以二叉树的线索化也有三种
a.二叉树的先序线索化
b.二叉树的中序线索化
c. 二叉树的后序线索化
4.二叉树的线索化说白了就是把那n+1个空指针利用起来,指向其前驱或者指向其后继。
*/
//二叉树采用顺序存储时的结点定义
typedef struct BTree{
ElemType data;
bool isEmpty;
}BTree;
//二叉树采用链式存储时的结点定义1 采用这种结点找孩子特别简单,但是找父亲特别难,需要从根节点遍历整个树。
typedef struct BiTNode{
ElemType data; //数据域
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode;
//二叉树采用链式存储时的结点定义2 采用这种结点找孩子特别简单,找父亲也特别简单。但是每个节点需要一个额外的存储空间来存储父节点的地址
typedef struct BiTNode2{
ElemType data; //数据域
struct BiTNode2 *lchild,*rchild; //左右孩子指针
struct BiTNode2 *parent; //父指针
int ltag,rtag; //线索二叉树需要用到的变量, 值为1时代表是线索,值为0时代表是孩子
}BiTNode2;
//队列的链表实现方式(带头结点)
typedef struct LNode{
BiTNode2 *address; //不需要将二叉树结点入队,只需要将二叉树的地址入队即可 这样可以节省内存空间。
struct LNode *next;
} LNode;
typedef struct QNode{ //队列指针
LNode *front,*rear;
}QNode;
//队列初始化
bool initQueue(QNode *queue){
LNode *head = (LNode *)malloc(sizeof(LNode));
//内存空间分配失败
if(head == null){
return false;
}
head->next = null;
queue->front = head;
queue->rear = head;
return true;
}
//队列判空
bool isEmpty(QNode *queue){
return queue->front == queue->rear;
}
//入队
bool EnQueue(QNode *que