【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码(一)

简介: 【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码

5.4.1 方式


  1. 由先根和中根遍历序列建二叉树
  2. 由后根和中根遍历序列建二叉树
  3. 由标明空子树的先根遍历建立二叉树
  4. 由完全二叉树的顺序存储结构建立二叉链式存储结构

5.4.2 由先根和中根遍历序列建二叉树


1)先根和中根原理

image.png

  • 总结:
  • 通过先序遍历获得根结点(第一个结点)
  • 通过根结点中序遍历确定左子树右子树

2)实例分析

image.png

image.png

3)练习

  • 练习1:

已经二叉树,先序序列为abcdefg,中序序列为cbdaegf,重建二叉树?

image.png

练习2:

已经二叉树,前序遍历序列为{1,2,4,7,3,5,6,8},中序遍历序列{4,7,2,1,5,3,8,6},后序遍历序列是?

image.png

练习3:

已知一棵树二叉树的先根遍历和中根遍历的序列分别为:A B D G H C E F I和G D H B A E C I F,请画出此二叉树,并写出它的后根遍的序列?

image.png

4)算法

/** 例如:new BiTree("ABDEGCFH","DBGEAFHC",0,0,8);* @param preOrder 先序遍历序列* @param inOrder  中序遍历序列* @param preIndex 在preOrder中开始位置* @param inIndex  在inOrder中开始位置* @param count 结点数*/publicBiTree(StringpreOrder,StringinOrder,intpreIndex,intinIndex,intcount) {
if(count>0) {
//1 通过先序获得根结点charr=preOrder.charAt(preIndex);
//2 中序中,根结点的位置inti=0 ;
for(; i<count ; i++) {
if(r==inOrder.charAt(i+inIndex)) {
break;
            }
        }
//3 通过中序,截取左子树和右子树root=newBiTreeNode(r);
root.lchild=newBiTree(preOrder,inOrder,preIndex+1, inIndex, i).root;
root.rchild=newBiTree(preOrder,inOrder,preIndex+1+i,inIndex+i+1, count-i-1).root;
    }
}

5.4.3 由后根和中根遍历序列建二叉树


1)后根和中根原理

image.png

总结:

  • 通过后序遍历获得根结点(最后一个结点)
  • 通过根结点中序遍历确定左子树右子树

2)练习

  • 练习1:

已知二叉树,中根遍历序列为:9,3,15,20,7、后根遍历序列为:9,15,7,20,3,重建二叉树?

image.png

练习2:

已知二叉树,中根遍历序列为:6,3,4,1,5,8,2,7、后根遍历序列为:3,6,1,8,5,7,2,4,前根遍历序列?

image.png

练习3:

已知一棵树二叉树的后根遍历和中根遍历的序列分别为:A C D B G I H F E和A B C D E F G H I,请画出该二叉树,并写出它的先根遍历的序列

image.png

5.4.4 由标明空子树的先根遍历建立二叉树


1)概述

  • 仅使用先根遍历序列无法唯一确定一颗二叉树,例如:“AB”,B可以是左孩子,也可以是右孩子。
  • 在先根遍历序列中加入==空树==信息,从而确定结点与双亲、孩子与兄弟间的关系,从而唯一确定一颗二叉树。
  • 空树:以字符“#”表示
  • 根节点A:以字符串“A##”表示
  • 下图树,以字符串“AB#C##D##”表示

image.png

2)算法

  • 建立二叉链表算法分析:
  • 若读取的字符是“#”,则建立空树;否则
  1. 建立根节点
  2. 递归建立左子树的二叉链表
  1. 递归建立右子树的二叉
  • 算法
privateintindex=0;          //用于记录preStr的索引值publicBiTree(StringpreStr) {
charc=preStr.charAt(index++);
if(c!='#') {
root=newBiTreeNode(c);
root.lchild=newBiTree(preStr).root;
root.rchild=newBiTree(preStr).root;
    } else {
root=null;
    }
}
相关文章
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
439 10
 算法系列之数据结构-二叉树
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
519 12
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
271 10
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
669 3
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
1245 10
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
408 59
|
11月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
234 0
栈区的非法访问导致的死循环(x64)
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
978 77
|
11月前
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
546 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】