C语言——数据结构之树与二叉树(下)(线索二叉树、树与二叉树的转换、哈夫曼树).docx
《C语言——数据结构之树与二叉树(下)(线索二叉树、树与二叉树的转换、哈夫曼树).docx》由会员分享,可在线阅读,更多相关《C语言——数据结构之树与二叉树(下)(线索二叉树、树与二叉树的转换、哈夫曼树).docx(10页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C语言数据结构之树与二叉树(下)(线索二叉树、树与二叉树的转换、哈夫曼树)前言 树的后半局部 将介绍线索二叉树 树以及二叉树的转换及哈夫曼树。 树的应用很多 内容主要集中在讲解算法思想 代码量有所减少 另外会附很多图以便讲解。 ps 一点废话 不咕咕了。这一篇比上篇会短小一点。 一、线索二叉树 1.引入局部 1 遍历二叉树是按某种规那么将非线性构造的二叉树结点线性化 2 遍历二叉树可得到结点的一个线性序列 在线性序列中 就存在结点的前驱以及后继 但是在二叉链表上只能找到结点的左孩子、右孩子 3 二叉树结点中没有相应前驱以及后继的信息。 如今的问题是 能否通过结点的两个链域查找出任一结点的前驱以
2、及后继 结点的前驱以及后继只有在每次遍历时动态产生 4 回首前面 我们使用了n个节点的二叉链表 有 2n个指针域 使用 n-1个指针 除根以外 每个结点被一个指针指向 空指针域数 2n- n-1 n 1 2.线索二叉树 1 定义 利用n 1个空链域存放结点的前驱以及后继信息 2 先序序列 ABCDEFGHK 线索 指向先序序列中的前驱以及后继的指针 那么产生一个问题 怎样判断一个指针终究是指向孩子 还是指向前驱或者后继 3 结点构造 为解决以上问题 在二叉链表中增加Ltag以及Rtag两个标志域 此时 链表结点包含5个域 lchild,Ltag,data,Rtag,rchild 考虑结点的左子
3、树 假设有 那么左链域lchild指示其左孩子 Ltag 0 否那么 令左链域lchild指示其前驱 Ltag 1 考虑结点的右子树 假设有 那么右链域rchild指示其右孩子 Rtag 0 否那么 令右链域rchild指示其后继 Rtag 1 3.整体构造 1 增设一个头结点 令其lchild指向二叉树的根结点 Ltag 0 Rtag 1 2 并将该结点作为遍历访问的第一个结点的前驱以及最后一个结点的后继 3 最后用头指针指示该结点 4 假设为空二叉树 只有一个头结点 其Ltag 0、Rtag 1, lchild与rchild都指向头结点自身 4.线索链表的类型描绘 /线索链表的类型描绘/定
4、义1个枚举类型PointerTag 其中Link 0,指针 Thread 1,线索 typedef enum Link,ThreadPointerTag;typedef struct BiThrNode TElemType data; struct BiThrNode *lchild,*rchild;/左右孩子指针 PointerTag LTag,RTag;/左右标志 BiThrNode,*BiThrTree;/*BiThrTree为指向BiThrNode的指针类型 1 称以这种BiThrNode结点构造构成的二叉链表为二叉树的线索链表 2 其中指示前驱以及后继的链域称为线索 3 加上线索的二
5、叉树称为线索二叉树 4 线索化 对二叉树以某规那么遍历使其变为线索二叉树的经过 如 按中序遍历得到的线索二叉树称为中序线索二叉树 按先序遍历得到的线索二叉树称为先序线索二叉树 按后序遍历得到的线索二叉树称为后序线索二叉树 5.中序线索链表的遍历算法 不需堆栈 非递归处理 1 目的 为了能更快的二叉树进展再次遍历 由于在线索链表中添加了以前遍历中得到的前驱以及后继的信息 进而可以简化遍历算法 2 考虑几个问题 中序遍历的第一个结点怎样找到 左子树上最左下的结点 在中序线索链表中怎样找到结点的后继 假设无右子树 那么为后继线索所指结点 否那么为对其右子树进展中序遍历时所访问的第一个结点 3 步骤:
6、 设置一个搜索指针p 先寻找中序遍历的首结点 即最左下角结点 当LTag 0时 表示有左孩子 p p- lchild, 直到LTag 1 无左孩子 已到最左下角 首先访问p- data 接着进入该结点的右子树 检查RTag以及p- rchild 1)假设该结点的RTag 1 表示有后继线索 那么p p- rchild,访问p- data 并重复1) 直到后继结点的RTag 0 2)当RTag 0时 表示有右孩子 那么应从该结点的右孩子开场 p p- rchild)查找左下角的子孙结点 即重复2 主要规那么 有后继找后继 无后继找右子树的最左子孙 /中序线索二叉树遍历void InOrderTr
7、averse_Thr (BiThrTreeT,void(*visit)(TElemType e) p T- lchild;/p指向根结点 while (p! T)/空树或者遍历完毕时 p T while (p- LTag Link)/第一个结点 p p- lchild; if (!visit(p- data)/访问其左子树为空的结点 return ERROR; while (p- RTag Thread p- rchild! T)/访问其后继结点 p p- rchild; visit(p- data); p p- rchild;/处理其右子树 二、树与二叉树的转换 1.树转换成二叉树 根据树的
8、二叉链表特征 可以制定以下转换规那么与步骤 1 加线 在树兄弟结点之间依次加一连线 2 抹线 对每个结点 除了其左孩子 第一个孩子 外 去掉其与其余孩子之间的关系 3 旋转 以树的根结点为轴心 将整树顺时针旋转45 转换之后的二叉树与其对应的二叉链表一样 根结点右子树一定为空 原来树中兄弟关系转换成了二叉树中双亲与右孩子的关系 2.二叉树转换成树 1 加线 恰好是上述中抹线的逆经过 恢复双亲与孩子的关系 假设p结点是双亲结点的左孩子 那么将p的右孩子 右孩子的右孩子 和沿分支找到的所有右孩子 都与p的双亲用线连起来、 2 抹线 抹掉原二叉树中双亲与右孩子之间的连线 他们在树中本为兄弟 无需连线
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 数据结构 二叉 线索 转换 哈夫曼树
限制150内