赞
踩
二叉树是n(n>=0)个结点的有限集合
或者为空二叉树,即n=0
或者由一个根结点和两个互不相交的被称作根的左子树和右子树组成。
每个结点至多只有两棵子树
左右子树不能颠倒(二叉树是有序树)
二叉树是递归定义的数据结构
树转化为二叉树:左孩子,右兄弟
1.满二叉树
特点
2.完全二叉树
当且仅当其每个结点都与高度为h的满二叉树中编号为1-n的结点一-对应, 称为
完全二叉树
特点
3. 二叉排序树
左子树上所有结点的关键字均小于根节点的关键字;右节点上所有结点的关键字均大于根节点的关键字,左子树和右子树又各是一棵二叉排序树。
用于元素的排序,搜索
4.平衡二叉树
树上任一结点的左子树和右子树的深度之差不超过1
平衡二叉树能有更高的搜索效率
顺序存储
#define MaxSize 100
struct TreeNode {
ElemType value; //结点中的数据元素
bool isEmpty; //结点是否为空
};
TreeNode t [MaxSize] ;
只适合存储完全二叉树
链式存储
//二又树的结点(壁式存储)
typedef struct BiTNode(
ELemType data;//数据域
struct BiTNode *lchld,rchild;//左、右孩子指针
}BiTNode,*BTree;
n个结点的二叉链表共有n+ 1个空链域
按照某种次序把所有节点都访问一遍
先序遍历——O(n)
根左右
得到前缀表达式
中序遍历——O(n)
左根右
得到中缀表达式(未加界限符)
后序遍历——O(n)
左右根
得到后缀表达式
求树的深度
int treeDepth(BiTree T){
if (T == NULL) {
return 0;
}
else {
int 1 = treeDepth(T->lchild);
int r = treeDepth(T->rchild);
//树的深度=Max(左子树深度,右子树深度)+1
return l>r ? 1+1 : r+1;
}
}
层次遍历
//层序遍历
void Levelorder(BiTree T){
LinkQueue Q;
InitQueue(Q) ; //初始化辅助队列
BiTree p;
EnQueue(Q,T); //将根结点入队
while( !IsEmpty(Q)){ //队列不空则循环
DeQueue(Q,p); //队头结点出队
visit(p); //访问出队结点
if(p- >lchild!=NULL)
EnQueue(Q, p- >lchild); //左孩子入队
if(p->rchild!=NULL)
EnQueue(Q,p >rchild); //右孩子入队
}
}
//二叉树的结点(链式存储)
typedef struct BiTNode{
char data;
struct BiTNode *lchild, 电rchild;
}BiTNode, *BiTree;
//链式队列结点
typedef struct LinkNode{
BiTNode * data;
struct LinkNode *next;
}LinkNode;
typedef struct{
LinkNode *front, *rear; //队头队尾
}LinkQueue;
由遍历序列构造二叉树
若只给出-一个二叉树的前/中/后/层序遍历队列中的一-种,不能唯- -确定-棵二叉树
前序+中序遍历队列
后序+中序遍历队列
层序+中序遍历队列
前序、后序、层序
序列的两两组合无法唯一
确定一棵二叉树
线索二叉树的作用——方便从一个指定结点出发,找到其前驱、后继;方便遍历线索二叉树的存储结构
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild, *rchild;
int ltag, rtag; //左、 右线索标志
}ThreadNode ,*ThreadTree ;
//*Ichild | Itag | data | rtag |*rchild
//tag==0,表示指针指向孩子
//tag==1,表示指针是"线索"
三种线索二叉树
先序线索二叉树——线索指向、 先序前驱、先序后继
中序线索二叉树——线索指向、中序前驱、中序后继
后序线索二叉树——线索指向、后序前驱、后序后继
二叉树的线索化
中序线索化得到中序线索二叉树
先序线索化-得到先序线索二叉树
后序线索化得到后序线索二叉树
核心
中序/先序/后序遍历算法的改造,当访问一个结点时,连接该结点与前驱结点的线索信息
用一个指针pre记录当前访问结点的前驱结点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。