一.数组的存储地址
1.一维数组
arr[i]的地址 = 首地址 + i x 元素大小
2.二维数组(行优先)
arr[ i ][ j ]的地址 =首地址 + (i x 列数 + j)x 元素大小
3.二维数组(列优先)
arr[ i ][ j ]的地址 =首地址 + (i x 行数 + j)x 元素大小
二.树
是n个节点的有限集。
在任意一颗非空树:
1.有且只有一个根节点。
2.当n>1时,其余节点可分为m(m>0)个互不交互的有限集,其中每一个集合本身又是一棵树,
并称为根的子树。
三.二叉树
1.
二叉树:每个节点最多有两个子节点的树结构。
二叉树的子树顺序不能颠倒
1.二叉树第i层最多有 2^(i-1)个节点(i>=1)。
2.深度为k的二叉树最多有2^k - 1个节点。(k>=1).
3.对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
完全二叉树:(最后一层可以不满)
一棵二叉树,除了最后一层外,其他层都是满的,且最后一层的节点从左到右连续排列。
2.遍历方式
1. 先序遍历
步骤:
1.访问当前根节点。
2.递归遍历左子树。
3.递归遍历右子树。
2. 中序遍历
步骤:
1.递归遍历左子树。
2.访问当前根节点。
3.递归遍历右子树。
3. 后序遍历
步骤:
1.递归遍历左子树
2.递归遍历右子树。
3.访问当前根节点。
4.层序遍历:
按照从上到下、从左到右的顺序,一层一层地访问二叉树的节点。
| 类型 | 定义 | 节点数 | 特点 |
|---|---|---|---|
| 满二叉树 | 所有层都满 | 2^h - 1 | 最严格 |
| 完全二叉树 | 除最后一层外全满,最后一层从左到右连续 | 2^(h-1) ~ 2^h - 1 | 较严格 |
| 平衡二叉树 | 左右子树高度差 ≤ 1 | 任意 | 高度平衡 |
| 二叉搜索树 | 左 < 根 < 右 | 任意 | 有序 |
| 普通二叉树 | 无限制 | 任意 | 最宽松 |
满二叉树是指每个非叶节点都有两个子节点且叶子节点没有子节点。
四.赫夫曼树
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优 二叉树,也称为哈夫曼树(Huffman Tree)。
哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
1.赫夫曼编码:
一种变长编码,根据字符出现的频率来构造最优前缀码,频率高的字符用短编码,频率低的字符用长编码。
2.赫夫曼编码优点:
WPL(Weighted Path Length):所有叶子节点的权值乘以路径长度之和。
WPL = Σ(叶子节点权值 × 叶子节点路径长度) 路径长度 = 从根到该叶子节点的边数(或节点数 - 1)
| 压缩效率高 | 频率高的字符编码短,WPL 最小 |
| 无歧义解码 | 前缀码特性,不会产生歧义 |
| 自适应性强 | 根据数据频率自动调整编码 |
| 理论最优 | 在变长编码中是最优前缀码 |
| 广泛应用 | 文件压缩、图像压缩等 |
前缀码:任何一个字符的编码都不是另一个字符编码的前缀。
赫夫曼树的叶子节点权值 = 字符频率;
内部节点权值 = 左右孩子权值之和。
贪心算法:每次选权值最小的两个节点合并,新节点权值为两者之和。
1. 将每个字符看作一个叶子节点,权值为频率 2. 从森林中选出权值最小的两个树 3. 合并这两棵树,新树根权值为两者之和 4. 将新树放回森林 5. 重复步骤 2-4,直到森林中只剩一棵树