一、二叉树的顺序存储
- 完全二叉树:
- 非完全二叉树(先要补成完全二叉树)
二、二叉树的链式存储
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node *lchild;
struct node *rchild;
} BTNode;
含有n个节点的二叉链表中,有n+1个空链域
三、二叉树的遍历
3.1递归算法
//先序遍历
void PreOrder(BTNode *&b){
if(b!=NULL){
printf("%c",b->data);
PreOrder(b->lchild);
PreOrder(b->rchild);
}
}
//中序遍历
void InOrder(BTNode *&b){
if(b!=NULL){
PreOrder(b->lchild);
printf("%c",b->data);
PreOrder(b->rchild);
}
}
//后序遍历
void PostOrder(BTNode *&b){
if(b!=NULL){
PreOrder(b->lchild);
PreOrder(b->rchild);
printf("%c",b->data);
}
}
3.2 非递归算法
中序遍历为例:
//中序遍历非递归方法
void InOrderStack(BTNode *&b){
if(b!=NULL){
stack<BTNode*> s;
BTNode *temp = b;
s.push(b);
while(b->lchild != NULL){
s.push(b->lchild);
b = b->lchild;
}
while(!s.empty()){
BTNode * top = s.top();
s.pop();
printf("%c",top->data);
if(top->rchild != NULL)
s.push(top->rchild);
}
}
}
3.3 层次遍历
借助队列
算法思想:
- 初始将根入队并访问根结点;
- 若有左子树,则将左子树的根入队;
- 若有右子树,则将右子树的根入队;
- 然后出队,访问该结点;
- 反复该过程直到队列空为止。
3.4 由遍历序列构造二叉树
3.5 线索二叉树
线索化
若无左子树,则将左指针指向其前驱结点;
若无右子树,则将右指针指向其后继结点。
先序线索二叉树
中序线索二叉树
后序线索二叉树
线索二叉树节点结构:
typedef struct ThreadNode {
ElemType data;
struct ThreadNode *1child, *rchild;
int ltag, rtag;
}ThreadTree;
一般中序线索树最重要:
寻找中序线索树的前驱节点:
若左指针为线索,则其指向结点为前驱结点
若左指针为左孩子,则其左子树的最右侧结点为前驱结点
寻找中序线索树的后驱结点.
若右指针为线索,则其指向结点为后驱结点
若右指针为右孩子,则其右子树的最左侧结点为后驱结点