数据结构04:树与二叉树

树的基本概念

树的定义
采用递归的方式定义树:树是若干个结点的结合,它由唯一的一个根结点和若干不相交的子树构成,每棵子树又是一棵树。
树的基本术语
结点:元素 + 分支(指针)
结点的度:结点的分支数

二叉树

二叉树的定义

  1. 每个结点最多只有两棵子树,即二叉树中每个结点的度只能是0,1,2
    这就说明二叉树有五种形态:空二叉树 + 只有跟结点的二叉树 + 只有左子树 + 只有右子树 + 左右子树都有
  2. 满二叉树(除了最后一层的叶子结点之外,其它结点都有左孩子和右孩子) + 完全二叉树(编号与满二叉树相同)

二叉树的主要性质

  1. 叶结点数 = 双分支结点数 + 1
    推导过程:总结点数 = 叶节点n0 + 单分支结点n1 + 双分支结点n2
    总分支数= n1 + 2n2
    总结点数 = 总分支数 + 1;
    即n0 + n1 + n2 - 1 = n1 + 2n2;
    n0 = n2 + 1;
  2. 第i层最多有2(i-1)个结点
  3. 深度为k的二叉树最多有2(k) - 1个结点(等比数列求和)
  4. 已知某结点的编号可推出其双亲结点编号 + 左孩子编号 + 右孩子编号
  5. n个结点的完全二叉树深度为:log2(n + 1)

二叉树的存储结构

  1. 顺序:不是很重要
  2. 链式
typedef struct BTNode {
    int data;
    struct BTNode *lchild;
    struct BTNode *rchild;
}BTNode;

二叉树的遍历算法

  1. 先序(pre) + 中序(in) + 后序遍历(post)

(如果要用到三个数据(结点数据 + 左孩子数据 + 右孩子数据),则对树的操作应该选用后序遍历,而且这种遍历方式用得相对多)

void preOrderTraverse(BTNode *p) {
    if(p != null) {
        visit(p);
        preOrderTraverse(p->rchild);
        preOrderTraverse(p->rchild);
    }
}
  1. 二叉树遍历的应用
    注意三点:选用哪种遍历方式 + 返回值(定义变量接受左右子树的值) + 叶结点与其它结点属性是否一样 + 有返回值的话要定义返回值接收的变量
    表达式求值p132 + 求树的高度(return LD RD中大的 + 1)
    层次遍历
void level(BTNode *p) {
    //①定义和初始化循环队列(循环队列中存储的是BTNode指针)
    int rear,front;
    BTNode *que[maxSize];
    rear = front = 0;
    BTNode *q;
    //②根节点入队
    if(p != null) {
        rear = (rear + 1) % maxSize;
        que[rear] = p;
        //③队列不为空时,循环访问队列(出队 + 入队)
        while(rear != front)
        {
            //先访问结点
            front = (front + 1) % maxSize;
            q = que[front];
            visit(q);
            //左右子树入队
            if(q ->lchild !=null) {
                rear = (rear + 1) % maxSize;
                que[rear] = q ->lchild;
            }
            if(q ->rchild !=null) {
                rear = (rear + 1) % maxSize;
                que[rear] = q ->rchild;
            }
        }
    }
}

线索二叉树的基本概念和构造

  1. 线索二叉树的由来:充分利用二叉树中的空指针域,更有效对二叉树进行遍历
    这里写图片描述
  2. 线索二叉树的定义
typedef struct TBTNode {
    char data;
    //0表示lchild(rchild)指针,1表示指向结点的直接前驱(后继)
    int lflag,rflag;
    struct TBTNode *lchild,rchild;
}TBTNode;

(知道先序、中序、后序结点就能知道这些线索索引的指向了)

树和森林

  1. 树与二叉树的转换:孩子为左结点 + 兄弟为右结点
  2. 森林与二叉树的转换:将森林中每棵树转换成二叉树 + 将其它二叉树作为上一棵二叉树的右子树
  3. 树和森林的遍历:先根遍历(转化为二叉树的先序遍历) + 后根遍历(转化为二叉树的中序遍历)

树与二叉树的应用

  1. 二叉排序树和平衡二叉树(放到查找那一章节讲)
  2. 郝夫曼树和郝夫曼编码
    1、郝夫曼树的概念
    ①郝夫曼树:带权路径最短的二叉树,又叫最优二叉树
    ②结点的带权路径长度:根节点到该结点的路径长度 X 该节点的权值
    ③树的带权路径长度(WPL):所有叶子结点的带全路径长度
    找一个例子理解这些概念(P143)
    2、郝夫曼树(最优二叉树)的构造方法
    构造:选最小的两个结点组合
    特点:不唯一 + 但是所构造的郝夫曼树的带权路径长度唯一且最小
    3、郝夫曼编码
    前缀编码:任意一字符的编码,都不是另一个字符编码的前缀
    郝夫曼编码:长度最短的前最编码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值