数据结构期末复习三:树和二叉树

本文详细介绍了树的基本概念,包括树的定义、度、叶子和内部结点等。深入探讨了二叉树的定义、性质、存储结构,特别是顺序存储和链式存储。此外,文章还涵盖了二叉树的遍历,包括递归和非递归方法,以及线索二叉树的构建和访问策略。最后,提到了Huffman树在数据压缩中的应用。
摘要由CSDN通过智能技术生成

一、树的定义和概念

定义

是n(n≥0)个结点的有限集(n=0为空树)。
任意⼀一棵⾮非空树中满⾜足如下条件:
1.有且仅有⼀一个特定的称为根(root) 的结点
2.其余n-1个结点可以划分成m(m>0)个互不相交的有限集,称为根root的子树

表示方法:
树型表示法,文氏图表示法,括号表示法,凹入表示法

基本术语

结点:包含一个数据元素及若干指向其子树的分支
结点:结点拥有的子树个数
:树内各结点度的最大值
叶子(终端结点):度为0的结点
分支结点、内部结点:度不为0的结点

结点的子树的根称为该结点的孩子
相应地,该结点称为孩子的双亲
同⼀双亲的孩子之间互称兄弟
其双亲在同一层的结点互为堂兄弟
结点的祖先是从根到该结点经过的所有结点
以某结点为根的子树的任一结点称为该结点的子孙

树的深度(高度):结点的最大层次

有序树:树中各结点的子树从左到右有次序不可调换

路径:存在一个结点序列ki,ki1,ki2,…,kin,kj,使得序列列中除ki外 的任⼀结点都是其在序列列中的前⼀个结点的后继,称这结点序列(ki,ki1,ki2,…,kj)为由ki到kj的一条路径
路径的长度 等于路径所通过的结点数目减1(即路径上分支数目)。

树的三种运算:
1.寻找满足某种关系的结点
2.遍历
3.插入和删除

二、二叉树

定义

满足以下两个条件的树形结构:
1.每个结点的度都不大于2
2.每个结点的孩子结点次序不能随意颠倒(左孩子和右孩子)

性质

1.第i层最多有2^(i-1)个结点
2.深度为k的二叉树至多有2^k-1个结点(满二叉树
3. 对任意一棵二叉树,若终端结点数为n0,度为 2的结点数为n2,则n0=n2+1
证明:设二叉树中结点总数为n,n1为二叉树中度为1 的结点总数,设二叉树中分支数目为B 。 ①n=n0+n1+n2
除根结点外,每个结点均对应一个进入它的分支: ②n=B+1
二叉树中的分支都是由度为1和度为2的结点发出 ③B=n1+2n2

完全二叉树:深度为k,结点为n的二叉树,结点1~n的位置序号与满二叉树的位置序号一一对应

满二叉树一定是完全二叉树
完全二叉树不一定是满二叉树

4.具有n个结点的完全二叉树深度为 ⎣log2n⎦+1或⎡log2(n+1)⎤

5.:对完全二叉树中编号为i的结点,
(1)若i=1,则结点i是二叉树的根,无双亲;
若i>1,双亲结点的编号为⎣i/2⎦
(2)若有左孩子结点,则左孩子结点的 编号为2i;
若有右孩子结点,则右孩子 结点的编号为(2i+1)
(3)若n为奇数,每个分支结点都既有左孩子结点,也有右孩子结点;
若n为偶数,则编号最大的分支结点 (编号为n/2)只有左孩子结点,没有右孩子结点

存储

分为顺序存储结构和链式存储结构

顺序存储结构

#define MAX_TREE_SIZE 100;
typedef TElemtype SqBiTree[MAX_TREE_SIZE];
SqBiTree bt;

编号从小到大的顺序是存储单元的顺序

链式存储结构

typedef struct BiTNode{
	struct BiTNode *lchild,rchild;
	TElemtype data;
}BiTNode,*BiTree;

三、遍历二叉树

三种遍历⽅方法的递归定义
先序遍历(DLR)
操作过程: 若二叉树为空, 则空操作, 否则:
(1) 访问根结点
(2) 按先序遍历左子树;
(3) 按先序遍历右子树。
中序遍历(LDR)
操作过程: 若二叉树为空,则空操作,否则: (1) 按中序遍历左子树;
(2) 访问根结点;
(3) 按中序遍历右子树。
后序遍历(LRD)
操作过程: 若二叉树为空, 则空操作, 否则: (1) 按后序遍历左子树;
(2) 按后序遍历右子树;
(3) 访问根结点。

算术式的二叉树表示
前缀:(波兰表达式)
中缀
后缀:(逆波兰表达式)

遍历递归算法

typedef struct BiTNode{
	struct BiTNode *lchild,*rchild;
	TElemtype data;
}BiTNode,*BiTree;

//先序遍历
void PreOrderTraverse(BiTree T){
	if(T!=NULL){
		printf("%d",T->data);
	}
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
} 
//中序遍历
void InOrderTraverse(BiTree T){
	if(T!=NULL){
	InOrderTraverse(T->lchild);
	printf("%d",T->data);
	InOrderTraverse(T->rchild);
	}	
}
//后序遍历 
void PostOrderTraverse(BiTree T){
	if(T!=NULL){
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		printf("%d",T->data);
	}
}

遍历非递归算法

typedef struct{
	struct SqStack *base;
	struct SqStack *top;
	int stacksize;
}SqStack;
 
SqStack InitStack(SqStack &S){
	S.base=(SqStack *)malloc(STACK_INT_SIZE*sizeof(SqStack));
	S.base=S.top;
	S.stacksize=STACK_INT_SIZE);		
} 

//先序 
void PreOrderTraverse(BiTree T){
	SqStack S;
	S=InitStack(S);
	Push(S,T);
	while(!StackEmpty(S)){
		BiTree p;
		pop(S,p);
		if(p->rchild) Push(S,p->rchild);
		if(p->lchild) Push(S,p->lchild);
	}
}

//中序
void InOrderTraverse(BiTree T){
	SqStack S;
	S=InitStack(S);
	BiTree p=T;
	while(p||!StackEmpty(S)){
		if(p){
			Push(S,p);
			p=p->lchild;
		}else{
			Pop(S,p);
			p=p->rchild;
		}
	}
} 
//后序

创建二叉链表

按先序序列建立二叉链表:

void CreateBiTree(BiTree &T){
	scanf(&ch);
	if(T=='.') T=NULL;
	else{
		T=(BiTree)malloc(sizeof(BiTNode));
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
} 

四、线索二叉树

有2n-(n-1)=n+1个空链域,利用这些空链域存放前驱和后继的信息。

LTag:
0 lchild域指示结点的左孩⼦
1 lchild域指示结点的遍历前驱
RTag:
0 rchild域指示结点的右孩⼦
1 rchild域指示结点的遍历后继

指向前驱和后继结点的指针叫做线索
以这种结构组成的二叉链表作为二叉树的存储结构,叫做线索链表
对二叉树以某种次序进行遍历并且加上线索的过程叫做线索化
线索化了的二叉树称为线索二叉树

线索二叉树的数据结构

//线索二叉树
typedef struct BiThrNode{
	TElemtype data;
	int LTag,RTag;
	struct BiThrNode *lchild,*rchild;
}BiThrNode,*BiThrTree; 

访问线索二叉树

#### 中序线索二叉树查找前驱后继
//中序 直接前驱
BiThrTree PreNode(BiThrTree p){
	pre=p->lchild;
	if(p->LTag==0){
		while(pre->RTag==0){
			pre=pre->rchild;
		}
		return pre;
	}
} 
//中序 直接后继 
BiThrTree PostNode(BiThrTree p){
	post=p->rchild;
	if(p->RTag==0){
		while(post->LTag==0){
			post=post->lchild;
		}
	}
	return post;
}
中序遍历线索二叉树
后序线索二叉树查找前驱后继

/

/后序 直接前驱
BiThrTree PreNode(BiThrTree p){
	if(p->LTag==1)	pre=p->lchild;
	else{
	if(p->RTag==0)	pre=p->rchild;
	if(p->RTag==1)	pre=p->lchild;
	}
} 

//后序 直接后继 
BiThrTree PostNode(BiThrTree p){
//需要知道双亲
} 
建立线索化链表

Hufffman树

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值