树与二叉树
定义
树(n个结点的有限集,递归的定义)
树的基本术语
二叉树定义(运算简单易实现)
基本形态
案例引入
数据编码
求解表达式
二叉树抽象数据类型定义
二叉树性质和储存结构
性质1,2(结点个数)
- 最少1个结点
- 最少k个
性质3 (叶子树与度为2的节点数关系)
- 从下往上分析,从上往下分析边与结点关系
性质4,5(完全二叉树)
满二叉树
完全二叉树
完全二叉树性质
储存结构
顺序
- 按满二叉树结点此次编号依次存放,Binary Tree
# define MAXSIZE 100
typedef TElemType SqBiTree[MAXSIZE];
SqBiTree bt;
链式
二叉链式
typedef struct BiNode{
TElemType data;
struct BiNode *lchild,*rchild;
}BiNode,*BiTree;
三叉链式
typedef struct TriNode{
TElemType data;
struct TriNode *lchild,*parent,*rchild;
}TriNode,*TriTree;
遍历二叉树与搜索二叉树
遍历二叉树
遍历
遍历方法
- 规定先左后右,
- DLR,先(根)序遍历
- LDR,中(根)序遍历
- LRD,后(根)序遍历
例子
序列确定二叉树
遍历实现
Status PreOrderTraverse(BiTree T){
if(T==NULL) return OK;
else{
printf("%d\t",T->data);// visit(T);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void Pre(BiTree T){
if (T!=NULL)
{
printf("%d\t",T->data);
Pre(T->lchild);
Pre(T->rchild);
}
}
Status InOrderTraverse(BiTree T){
if(T==NULL) return OK;
else{
InOrderTraverse(T->lchild);
printf("%d\t",T->data);// visit(T);
InOrderTraverse(T->rchild);
}
}
Status PostOrderTraverse(BiTree T){
if(T==NULL) return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%d\t",T->data);// visit(T);
}
}
非递归算法
中序遍历非递归算法(栈)
Status InOrderTra(BiTree T){
BiTree p,q;
SqStack S;
InitStack(S);
p=T;
while(p||!EmptyStack(S)){
if(p)
{
Push(S,p);
p=p->lchild;}
else{
PopStack(S,q);
printf("%c",q->data);
p=q->rchild;
}
}
return OK;
}
层次遍历
typedef struct{
BTNode data[MAXSIZE];
int front,rear;
}SqQueue;
二叉树遍历算法的应用
二叉树的建立
Status CreateBiTree(BiTree &T){
char ch;
cin>>ch;
if(ch == '#') T=NULL;
else{
if(!(T=new BiTNode)) exit(OVERFLOW);
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
二叉树复制
Status CopyBiTree(BiTree T,BiTree &NewT){
if(T == NULL) {NewT=NULL;return 0;}
else{
NewT = new BiTNode;
NewT->data=T->data;
CopyBiTree(T->lchild,NewT->lchild);
CopyBiTree(T->rchild,NewT->rchild);
}
return OK;
}
计算二叉树深度
int DepthBiTree(BiTree T){
int m,n;
if(T == NULL) {return 0;}
else{
m = DepthBiTree(T->lchild);
n = DepthBiTree(T->rchild);
if(m>n) return m+1;
else return n+1;
}
}
计算结点个数
int NodeBiTree(BiTree T){
if(T == NULL) {return 0;}
else{
return NodeBiTree(T->lchild)
+NodeBiTree(T->rchild)+1;
}
}
计算结点节点数
int LeaveBiTree(BiTree T){
if(T == NULL) {return 0;}
if(T->lchild==NULL&& T->rchild==NULL)
return 1;
else{
return LeaveBiTree(T->lchild)
+LeaveBiTree(T->rchild);
}
}
线索二叉树
- 找某种遍历方法下的前驱和后继
树与森林
定义
树的存储结构
双亲表示法
- 双亲简单,找孩子难
typedef struct PTNode{
TElemType data;
int parent;
}PTNode;//结点结构
typedef struct{
PTNode node[MAXSIZE];
int r,n;//根节点,结点数
}PTree;//tree
孩子链表
- 找孩子容易,双亲难
typedef struct CTNode{
int child;
struct CTNode *next;
}*ChildPtr;//孩子结点结构
typedef struct{
TElemType data;
ChildPtr firstchild;//根节点,结点数
}CTBox;//双亲结点结构
typedef struct
{
CTBox nodes[MAXSIZE];
int r,n;
}CTree;
带双亲的孩子链表-结合
- 孩子链表基础上增加双亲结点下标
孩子兄弟表示法(二叉树)
- 指向第一个孩子和下一个兄弟结点
typedef struct CSNode{
TElemType data;
struct CSNode *firstchild,*firstsibling;
}CSNode,*CSTree;
树与二叉树的转换
树
森林
树和森林的遍历
树的遍历
- 没有中序
- 先序,后序,层次
森林的遍历
先序遍历
中序遍历