离散数学——通俗易懂的描述:无向树&生成树

一.无向树

1.定义:

树:不含简单回路的连通图

无向树:不含简单回路的无向连通图

森林:每个连通分支都是树的无向图

树叶:d(v)=1

分枝点:d(v)>=2

平凡树:平凡图(没有树叶,没有分枝点)

!!!补充:六个等价定义~~~

(1)G是树(没有回路,连通)

(2)G任意两个顶点之间存在唯一路径(和(5)一起记忆)

(3)G连通且m=n-1(m=n-1要牢牢记住!)

(4)G无圈且m=n-1(m=n-1要牢牢记住!)

(5)G连通且每条边都是桥(理解:每条边都很重要!)

(6)G无圈,若在任意两顶点之间加一条新边,就是G中唯一的一个圈

2.性质

定理:任一n阶非平凡无向树 至少有两片树叶

(你见过只有一片叶子就能构成的一棵树的吗???)

3.例题(3个)

 

                                   

4.无向树的棵树

(计算过程和公式就不讲了,挺麻烦的,tn表可以瞅瞅)

tn表:n阶无向树对应的棵树,给定n,查表得到tn

二.生成树

1.定义:

生成树T:G的生成子图,且为树

树枝:既在G中,也在T中的边

弦:在G中,但不在T中的边

余树:T的补图

(注意啦:余树虽然名字里面有树,但不一定是树!!!)

符号表示更清晰:

2.找简单图的生成树——破圈法

3.生成树的存在性定理:无向图G有生成树<==>G连通

推论:

(1)G为无向连通图==>(m>=n-1)(理解:有n-1条边用来当生成树了~)

(2)T为无向连通图G的一个生成树==>T的余树的边数为(m-n+1)(理解:有n-1条边用来当生成树了,剩下的就是余树的边~)

(3)T为连通图G的一个生成树,C是G中任意圈==>T的余树的边肯定参与构成C的边

符号表示:

     

  4.定理(不理解不要着急,直接看例子就好)

三.基本回路&基本割集

1.定义:看文字似乎很难理解,可以结合例题

四.求生成树的个数

1.如何计算

2.标定完全图的生成树个数

定理:

五.长度为(n-2)的序列与生成树T的相互转换

1.T==>长度为(n-2)的序列

(看不懂符号描述就看例题┗|`O′|┛ 嗷~~~我也觉得有点小难呜呜呜,可以随时评论区留言或者问我,我回消息很快~~)

2.T<==长度为(n-2)的序列

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哈夫曼树是一种特殊的二叉树,用于压缩数据。它的特点是,将频率较高的字符用较短的编码表示,而将频率较低的字符用较长的编码表示,以达到压缩数据的目的。 哈夫曼树的构建过程如下: 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` 函数来生成编码表,最后输出每个字符的编码。 需要注意的是,这个代码中只考虑了字符的权值,实际应用中还需要考虑字符的出现次数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值