概念

  1. 树是n个结点的有限集合
  • 有且仅有一个特定的称为根的结点。
  • 当n>1时,其余结点可分为m(m>0)个互不相交的有限集合,其中每一个集合本身又是一棵树,称为根结点的子树。

☆n个结点的树中有n-1条边。

  1. 基本术语:
  • 祖先结点和子孙结点
  • 双亲结点和孩子结点
  • 兄弟结点
  • 度:树中一个结点的子结点
  • 结点的层次
  • 结点的高度
  • 结点的深度
  • 树的高度:树种结点的最大层数

二叉树

存储结构

typedef struct BitNode {
	int data;
	struct BitNode *lchild, *rchild;
}BitNode, *BitNode;

  • 遍历
    先序遍历:
    若二叉树非空:
    (1)访问根结点
    (2)先序遍历左子树
    (3)先序遍历右子树

线索二叉树

线索化

若无左子树,则将左指针指向其前驱结点
若无右子树,则将右指针指向其后继结点

结构

ltaglchilddatarchildrtag
  • tag=0 左(右)孩子
  • tag=1 前(后)继

中序线索二叉树

void InThread(ThreadTree &p,ThreadTree &pre)
{
if(p!=NULL){
InThread(p->lchild,pre);
if(p->lchild==NULL){
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre-<rchild==NULL)
{
pre->rchild=p
pre->rtag=1;
}
pre=p;
InThread(p->rchild,pre);
 }
}
void CreateInThread(ThreadTree T)
{
ThreadTree pre=NULL;
if(T!=NULL){
InThread(T,pre);
pre->rchild=NULL;
pre->tag=1;
 }
}
  • 中序线索二叉树遍历
ThreadNode *Firstnode(ThreadNode *p){
while(p->tag==0)
p=p->lchild;
return p;
}
ThreadNode *Nextnode(ThreadNode *p){
if(p->rtag==o)
return Firstnode(p->rchild);
else return p->rchild;
}
void Inoder(ThreadNode *T){
for(ThreadNode *p=Firstnode(T);p!=NULL;p=Nextnode(p))
visit(p);
}

树的存储结构

  • 双亲表示法
    采用一组连续的存储空间来存储每个结点,同时在每个节点中增设一个伪指针,指示双亲结点在数组中的位置。根结点的下标为0,其伪指针域为-1。
#define MAX_TREE_SIZE 100
typedef struct{
ElemType data;
int parent;
}PTNode;
typedef struct{
  PTNode nodes[MAX_TREE_SIZE];
  int n;
}PTree;
  • 孩子表示法
    将每个结点的孩子结点都用单链表连接起来形成一个线性结构,n个结点具有n个孩子链表
#define MAX_TREE_SIZE 100
typedef struct{
int child;
struct CNode *next;
}CNode;
typedef struct{
ElemType data;
struct CNode *child;
}PNode;
typedef struct{
PNode nodes{MAX_TREE_SIZE};
int n;
}CTree;
  • 孩子兄弟表示法
    以二叉链表作为树的存储结构,又称二叉树表示法

二叉排序树BST

也称二叉查找树。

  • 左子树结点值<根结点值<右子树结点值
  • 查找:
    若小于根结点时查找左子树,大于根结点时,查找右子树
BSTNode *BST_Search(BITREE T,ELEMTYPE key,BSTNode *&p){
p=NULL;
while(T!=NULL&key!=T->data){
p=T;
if(key<T->data)T=T->lchild;
else T=T->rchild;
}
return T;
}
  • 插入:
    小于根结点插入左子树,大于根结点插入右子树,等于根结点时不插入
int BST_Insert(BITree &T,KeyType k){
if(T==NULL){
T=(BITree)malloc(sizeof(BSTNode));
T->key=k;
T->lchild=T->rchild=NULL;
return 1;
}
else if(k==T->key)return 0;
else if(k<T->key)return BST_Insert(T->lchild,k);
else return BST_Insert(T->rchild,k);
}
  • 构造:
    同插入
void Create_BST(BITree &T,KeyType str[],int n){
T=NULL;
int i=0;
while(i<n){
BST_Insert(T,str[i]);
i++;
   }
}
  • 删除:
  1. 若被删除结点z是叶结点,则直接删除。
  2. 若被删除结点z只有一棵子树,则让z的子树成为z父节点的子树,代替z结点。
  3. 若被删除的结点z有两棵子树,则让z的中序序列直接后继代替z,并删去直接后继结点。

平衡二叉树

  • 任意结点的平衡因子的绝对值不超过一
    平衡因子:左子树高度-右子树高度
  • 高度为h的最小平衡二叉树的结点数Nh

平衡二叉树的判断

  • 利用递归的后序遍历过程:
  1. 判断左子树是一棵平衡二叉树
  2. 判断右子树是一棵平衡二叉树
  3. 判断以该结点为根的二叉树为平衡二叉树
void Judge_AVL(BiTree bt,int &balance,int &h)
{
int bl=0,br=0,hl=0,hr=0;
if(bt=NULL)
{
h=0;
balance=1;
}
else if(bt->lchild==NULL&&bt->rchild=NULL)
{
h=1;
balance=1;
}
else{
Judge_AVL(bt->lchild,bl,hl);
Judge_AVL(bt->rchild,br,hr);
if(hl>hr)h=hl+1;
else h=hr+1;
if(abs(hl-hr)<2&&bl==1&&br==1)
balance=1;
else balance=0;
}
}
  • 平衡二叉树的插入
    ( 先插入,再调整 )

哈弗曼树

带权路径长度

  • 路径长度:路径上所经历边的个数
  • 结点的权:结点被赋予的数值
    树的带权路径长度
  • 树中所有叶节点的带权路径长度之和,记为,
    WPL=∑WiLi

哈弗曼树:带权路径长度最小的树

上一节:串

下一节:树和森林

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值