通俗易懂的红黑树简析

一、基本概念

 红黑树本质上是一棵近似平衡的二叉树,它的节点只有两种颜色即红与黑,它满足二叉搜索树的基本性质,即树上的任何节点的值大于其左子节点(若左子节点存在),任何节点的值大于其右子节点的值(若右子节点存在)。

 近似平衡:深度最大的节点的深度<= 2 * 深度最小的节点的深度。具体如何保证这种近似平衡后面会说到。

 红黑树与平衡二叉树比较: 因为红黑树只追求近似平衡,所以在插入与删除节点时,翻转次数远远少于平衡树,因此在需要较多插入删除操作的场景中,使用红黑树更好。 同样也因为近似平衡,所以在查询时,红黑树查询的深度可能会大于平衡二叉树,所以在需要较多查询的场景中,使用平衡二叉树更好。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
哈夫曼树是一种特殊的二叉树,用于压缩数据。它的特点是,将频率较高的字符用较短的编码表示,而将频率较低的字符用较长的编码表示,以达到压缩数据的目的。 哈夫曼树的构建过程如下: 1. 将所有字符及其频率按照频率从小到大的顺序排列,构成一个森林,每个节点都是一棵只包含一个字符的树。 2. 从森林中选出两棵根节点权值最小的树,将它们合并成一棵新的树,新树的根节点的权值为两棵子树的权值之和。 3. 将新树插入到森林中,重复步骤2,直至森林中只剩下一棵树,即哈夫曼树。 下面是用C语言实现哈夫曼树的代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_TREE_SIZE 1000 typedef struct { int weight; // 权值 int parent; // 父节点在数组中的下标 int lchild, rchild; // 左右孩子在数组中的下标 } HTNode, *HuffmanTree; typedef char **HuffmanCode; // 编码表 // 选择两个权值最小的节点 void select(HuffmanTree tree, int n, int *s1, int *s2) { int min1 = 0, min2 = 0; for (int i = 1; i <= n; i++) { if (tree[i].parent == 0) { if (tree[i].weight < tree[min1].weight) { min2 = min1; min1 = i; } else if (tree[i].weight < tree[min2].weight) { min2 = i; } } } *s1 = min1; *s2 = min2; } // 构建哈夫曼树 void createHuffmanTree(HuffmanTree *tree, int *w, int n) { if (n <= 1) return; int m = 2 * n - 1; *tree = (HuffmanTree) malloc((m + 1) * sizeof(HTNode)); // 初始化前n个节点 for (int i = 1; i <= n; i++) { (*tree)[i].weight = w[i]; (*tree)[i].parent = 0; (*tree)[i].lchild = 0; (*tree)[i].rchild = 0; } // 构建哈夫曼树 for (int i = n + 1; i <= m; i++) { int s1, s2; select(*tree, i - 1, &s1, &s2); (*tree)[s1].parent = i; (*tree)[s2].parent = i; (*tree)[i].lchild = s1; (*tree)[i].rchild = s2; (*tree)[i].weight = (*tree)[s1].weight + (*tree)[s2].weight; } } // 生成哈夫曼编码 void createHuffmanCode(HuffmanTree tree, HuffmanCode *code, int n) { *code = (HuffmanCode) malloc((n + 1) * sizeof(char *)); char *temp = (char *) malloc(n * sizeof(char)); // 临时存储编码 for (int i = 1; i <= n; i++) { int start = n - 1; int j = i; int parent = tree[i].parent; while (parent != 0) { if (tree[parent].lchild == j) { temp[start] = '0'; } else { temp[start] = '1'; } start--; j = parent; parent = tree[j].parent; } (*code)[i] = (char *) malloc((n - start) * sizeof(char)); strcpy((*code)[i], &temp[start + 1]); } free(temp); } int main() { int n; scanf("%d", &n); int *w = (int *) malloc((n + 1) * sizeof(int)); for (int i = 1; i <= n; i++) { scanf("%d", &w[i]); } HuffmanTree tree; createHuffmanTree(&tree, w, n); HuffmanCode code; createHuffmanCode(tree, &code, n); // 输出每个字符的编码 for (int i = 1; i <= n; i++) { printf("%d: %s\n", i, code[i]); } return 0; } ``` 在这个代码中,我们定义了 `HTNode` 结构体来表示哈夫曼树的节点,用 `HuffmanTree` 来表示整棵树,用 `HuffmanCode` 来表示编码表。我们使用了 `select` 函数来选择两个权值最小的节点,使用 `createHuffmanTree` 函数来构建哈夫曼树,使用 `createHuffmanCode` 函数来生成编码表,最后输出每个字符的编码。 需要注意的是,这个代码中只考虑了字符的权值,实际应用中还需要考虑字符的出现次数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值