1.哈夫曼树
1.1 概念
- 给定n个权值作为n个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称为最优二叉树或哈夫曼树。
1.2 哈夫曼树的度只能为2或者0。
1.3 哈夫曼树是用来进行无损压缩和恢复的。
1.4 带权路径的计算
- 一条带权路径是从根节点到叶子节点的节点数L减去一再与叶子节点的权值相乘;将所有的带权路径相加得到的为WPL;
1.5 创建一棵哈夫曼树的步骤
- 1.将带权节点按权值大小从小到大进行排序;
- 2.用最小的两个节点构成一颗树(左孩子节点是两个中的小的,右孩子是两个中的大的,父节点是两个权值的和);
- 3.将新的节点(2中的父节点)放入序列中重新排序,重复执行以上过程;
1.6 编码方式:左0右1,顺着路径进行
1.7 创建一个哈夫曼树
#include <stdio.h>
#include <stdlib.h>
typedef struct tree
{
int n_value;
struct tree* p_left;
struct tree* p_right;
struct tree* p_father;
}HFM;
int* MySort(int arr[], int len)
{
int i, j, temp;
for (i = 0; i < len; ++i)
{
for(j=i+1; j<len; j++)
{
if(arr[i] > arr[j])
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
return arr;
}
HFM* CreateHFM(int arr[], int len)
{
HFM* p_tree = NULL;
int i;
int arr_temp[len] = {0};
p_tree = (HFM*)malloc(sizeof(HFM));
if(arr == NULL || len <= 0)return NULL;
for(i=0; i<len; i++)
{
arr_temp = MySort(arr, len-i);
}
}
2.图
2.1 图是有限节点集合V和链表节点的有限边的集合E的二元组合G=(V, E)。
2.2 图分为两类:
- 1.无向图:若图中所有的边均满足没有次序和方向性,即(V1, V2)和(V2, V1)表示同一条边,则称为无向图。
- 1.完全图:图中n个节点间所有可能的边均存在,即n个节点有 n*(n-1)/2 条边的图。
- 2.依附:边(V1,V2)依附于顶点V1,V2。
- 3.子图:若G’是图G的子图,则有V(G’)<=V(G),和E(G’)<=E(G)。
- 4.路径:图中从Vp到Vq的一条路径是指由顶点构成的连续序列Vp,Vi1,Vi2,…,Vin-1,Vin,Vq,其中(Vp,Vi1),(Vi1,Vi2),…,(Vin-1,Vin),(Vin,Vq)均为E(G)的边。
- 5.路径长度:路径所含边的数目即为路径的长度。
- 6.简单路径:指除了起点和终点可能相同外,其他顶点都不相同。
- 7.回路和环:起点和终点为同一顶点的简单路径称为回路或环。
- 8.联通:若从Vi到Vj有路径可通,则称顶点Vi和Vj是可通的。
- 9.连通图:图中任意两个节点都有路径相通,则称图为连通图。
- 10.非连通图:只要有两个节点无路径相通,则称为非连通图。
- 11.连通分量:图中的极大联通子图。
- 12.度:指无向图中顶点V相关的边的个数。
- 2.有向图:图中的边存在次序关系和方向性,即<V1, V2>和<V2, V1>代表两条不同的边,称为有向图。
- 1.完全图:有向图中有n个节点,并且共有 n*(n-1) 条边,称为完全图。
- 2.依附:边<V1, V2>依附于顶点V1和v2。
- 3.路径:图中从Vp到Vq的一条路径是指由顶点构成的连续序列Vp,Vi1,Vi2,。。。Vin-1,Vin,Vp,其中<Vp,Vi1>,<Vi1,Vi2>,…,<Vin-1,Vin>,<Vin,Vq>均为E(G)上的有向边。
- 4.强连通:如果每个相异成对顶点Vi和Vj都同时有从Vi到Vj和从Vj到Vi的路径,则称该有向图为强连通。
- 5.强连通分量:有向图中的极大强连通子图。
- 6.入度:顶点V的入度是指以V为终点有向边得个数。
- 7.出度:顶点V的出度是指以V为起点有向边得个数。
2.3 图的存储方式
2.4 如何选择存储方式