数据结构--树

第六章 树

树是n个结点的有限集,n=0时,称为空树,在任意一颗非空树中:

  • 有且仅有一个特定的称为根的结点(Root)
  • 当n>1时,其余结点可分为m个互不相交的有限集合(T1,T2,…,Tn),其中每个集合本身又是一棵树,并且车管我根的子树(Subtree)

这里写图片描述

6.1 树的定义

树的结点包含一个数据元素及若干个指向其子树的分支,结点拥有的子树数量称为结点的度。

结点的分类:

  • 叶结点/终端结点:度为0的结点
  • 分支结点/非终端结点:度不为0的结点

树的度:树内各个结点的度的最大值

树的路径长度:每个结点路径长度之和

这里写图片描述

上图的树的度为3

结点间的关系:

结点的子树的根称为该结点的孩子,该结点称为孩子的双亲,同一个双亲的孩子称为兄弟,结点的祖先是从根节点到该结点所经分支上的所有结点。

结点度之和=结点数-1

这里写图片描述

结点的层次:

层次(Level)从根开始定义,树中结点的最大层次称为树的深度(Depth)或高度。

这里写图片描述

有序树:树中结点的各个子树看成是从左至右有次序的,不能互换
无序树:可以互换

这里写图片描述

6.2 二叉树的定义

二叉树(Binary tree)是n个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根节点和两颗互不相交、分别称为根节点的左子树和右子树的二叉树组成。

6.2.1 特殊二叉树

1. 满二叉树

所有分支节点都存在左子树和右子树,并且所有叶子都在同一层上的二叉树。

2.完全二叉树

对一棵有n个结点的二叉树按层序编号,如果编号为i的结点与同样深度的满二叉树中编号为i的节点在二叉树中的位置完全相同,则成全完全二叉树。

这里写图片描述

6.2.2 二叉树的性质

  1. 在二叉树的第i层,至多有2i−1个结点

  2. 深度为k的二叉树最多有2k−1个结点

  3. 对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1

  4. 具有n个结点的完全二叉树的深度为**[log2n]+1**([x]表示不大于x的最大整数)

  5. 对任意二叉树n1为奇数,完全二叉树n1=0/1,哈夫曼树n1=0

6.2.3 二叉树的存储结构

1、二叉树的顺序存储结构

用一维数组存储二叉树中的结点,并且结点的存储位置,也就是数组的下标要能体现结点之间的逻辑关系。

完全二叉树:

这里写图片描述

一般二叉树:

可以将其按完全二叉树来编号,不过把不存在的结点设置为空而已:

这里写图片描述

这里写图片描述

但是这样一来会对存储空间浪费,所以顺序存储结构一般只用于完全二叉树

2、二叉链表

这里写图片描述

data->数据域,lchile和rchile->左孩子和右孩子的指针

这里写图片描述

6.3 二叉树的遍历

1、前序遍历

若二叉树为空,则空操作返回,否则先访问根节点,然后前序遍历左子树,再前序遍历右子树,下图遍历顺序为:ABDGHCEIF

这里写图片描述

void PreOrder(BiTree T){
    if(T !=NULL){
        visit(T);
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}

void PreOrder2(BiTree T){
    InitStack(S);
    BiTree p=T;
    while(p){
        if(p){
            visit(p);
            Push(S,p);
            p=p->lchild;
        }else{
            Pop(S,p);
            p=p->rchild;
        }
    }
}

2、中序遍历

若二叉树为空,则空操作返回,否则从根节点开始(并不访问),中序遍历左子树,然后访问根节点,最后中序遍历右子树,下图遍历顺序为:GDHBAEICF

这里写图片描述

void InOrder(BiTree T){
    if(T !=NULL){
        PreOrder(T->lchild);
        visit(T);
        PreOrder(T->rchild);
    }
}

void InOrder2(BiTree T){
    InitStack(S);
    BiTree p=T;
    while(p){
        if(p){
            Push(S,p);
            p=p->lchild;
        }else{
            Pop(S,p);
            visit(p);
            p=p->rchild;
        }
    }
}

3、后序遍历

若二叉树为空,则空操作返回,否则从左到右,先叶子后结点的方式遍历访问左右子树,最后访问根节点,,下图遍历顺序为:GHDBIEFCA,可以找到子节点到父节点的路径

这里写图片描述

void PostOrder(BiTree T){
    if(T !=NULL){
        PreOrder(T->lchild);
        PreOrder(T->rchild);
        visit(T);
    }
}

void PostOrder2(BiTree T){
    InitStack(S);
    BiTree q=T;
    BiTree r=NULL;
    while(q && IsEmpty(s)){			//结点和栈不空,则继续循环
        if(p){
            Push(S,q);
        	p=p->lchild;
        }else{
            GetTop(S,q);
            if(q->rchild && q-rchild!=r)	//右子树不空且未被访问过,则转向右子树
                q=q->rchild;
            else{					//若右子树已被访问,则弹出结点
                Pop(S,q);
                visit(q);
                r=q;
                q=NULL;
            }
        }
    } 
}

4、层序遍历

需要队列支持,若二叉树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,同一层中,按从左到右的顺序对结点逐个访问,遍历顺序为:ABCDEFGHI

这里写图片描述

void LevelOrder (BiTree T){
    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);	//如果右子树不空,则右子树结点入队
    }
}

5. 其他常用算法

1. 求树高
int BtDepth(BiTree T){
    if(T == NULL)
        return 0;
    ldep=BtDepth(T->lchild);
    rdep=BtDepth(T->rchild);
    if(ldep>rdep)
        return ldep+1;
    else
        return rdep+1;
}

6.4 线索二叉树

常考空指针域的情况和线索二叉树的缺陷

6.4 树、森林、二叉树的转换

6.4.1 树转换为二叉树

这里写图片描述

6.4.2 森林转换为二叉树

这里写图片描述

6.4.3 二叉树转换为树

这里写图片描述

这里写图片描述

6.4.4 二叉树转换为森林

这里写图片描述

这里写图片描述

6.5 树与森林的遍历

总结:树、森林的先根遍历对应二叉树的先序遍历后根遍历对应二叉树的后序遍历

6.6 平衡二叉树

  • n层平衡二叉树只少要m个结点(当非叶子结点的平衡因子均为1或-1时成立):n1=1,n2=2,n3=4,n4=7,n5=12,n6=20…
  • 平衡因子:左子树与右子树的高度差
  • 最后插入的叶子节点不一定还是叶子结点
  • 若删除叶子结点再插入,平衡二叉树可能相同可能不同
  • 若删除非叶子结点再插入,平衡二叉树可能相同可能不同

6.7 哈夫曼树

结点的带权路径:该结点到树根之间的路径长度与结点上权的乘积

树的带权路径:树中所有结点的带权路径长度之和

哈夫曼树:带权路径长度WPL最小的二叉树,称为哈夫曼树,也叫最优二叉树

这里写图片描述

1.哈夫曼编码

结点的带权路径:该结点到树根之间的路径长度与结点上权的乘积

树的带权路径:树中所有结点的带权路径长度之和

哈夫曼树:带权路径长度WPL最小的二叉树,称为哈夫曼树,也叫最优二叉树

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值