由于二叉树和树均可以用二叉链表作为存储结构,因此以二叉链表为媒介可以倒数树和二叉树的对应关系。一棵树可以找到唯一的一棵二叉树与之对应。反之,一棵右子树为空的二叉树也可以转换成对应的树。
将一棵树转化为二叉树的方法如下:
从树和二叉树的转换方式知,任何一棵树转换成二叉树,二叉树的右子树必为空。由此,我们可以把森林中的第二棵树的根结点看作第一棵树的根结点的兄弟,第三棵树的根结点看成是第二棵树的根结点的兄弟。
哈夫曼树,又称最优二叉树,是一类树的带权路径长度最小的二叉树。
定理:对于具有n个叶子结点的哈夫曼树,共有2n-1
个结点,其中有n-1
个非叶子结点。
称有序二元组
G=(V,E)
是一个图,若其中V
是一个非空有限集合(或称顶点集),V
中的数据元素称为顶点,E
是V
上的二元关系,称E
为边集。
(1).若E
中的顶点对(或序偶)(u,v)
是无序的,则称G
为无向图,称(u,v)
为G
的一条无向边,显然,(u,v)
和(v,u)
是指同一条边。
(2).若E
中的顶点对(或序偶)(u,v)
是有序的,则称G
为有向图。称(u,v)
为G
的一条有向边(或弧),其中,称u
为弧尾(或始点),称v
为弧头(或终点)。
G=(V,E)
中,若e=(u,v)
是G
中的一条边,u
和v
称为边e
的两个端点,称边e
关联u
和v,
也称u
邻接v
,或v
邻接u
,u
和v
称为边e=(u,v)
的邻接点;若u=v
,称(u,v)
为G
的自环。对于任意的u
属于V
,若不存在任何边关联u
,说明顶点u
是孤立点。G=(V,E)
为一个图,且|V|=n,|E|=m
。若无向图中每两个顶点间都存在一条边,或在有向图中每两个顶点间都存在着方向相反的两条有向边,则称此图为完全图。显然,无向图包含n(n-1)/2
条边,有向图包含n(n-1)
条边。(m称为稀疏图,反之称为稠密图。
G=(V,E)
中,对于每一个v
属于V
,称关联顶点v
的边数为顶点v
的度数,记为d(v).
在有向图G=(V,E)中,对于每一个v属于V,称以v为始点的边的条数为v的出度,称以v为终点的边的条数为v的入度。在无向图中,顶点的度数之和与边数有如下关系:权和网:在某些图中,边或弧上具有与它相关的数据信息称之为权。在实际应用中,权值可以有某种含义。例如,在城市交通线路的图中,边上的权值可以来表示该线路上的长度或交通费用等。边上带权的图称为带权图,也称网。
生成树:包含G
的n
个顶点的极小连通子图称为图G
的生成树。一棵具有n
个顶点的生成树有且仅有n-1
条边。
例题:图
G=(V,E)
是一个非连通无向图,共有36
条边,则该图至少有多少个顶点?
该非连通无向图至少由一个顶点和一个连通无向图组成。
(n-1)n/2=36,n=9
,所以该图至少有10
个顶点。
ADT Graph{
数据对象:
D = V = {ai|1<=i<=n,ai属于Elemtype}
数据关系:
R = E = {(ai,aj)|1<=i<=n,1<=j<=n,ai,aj属于D}
基本操作:
InitGraph(&g,V,E);//初始化创建一个图
DestroyGraph(&g);//摧毁图,释放图占用的存储空间
LocateVex(g,v);//查找顶点v在图中的位置
InsertVex(&g,v);//在图中插入一个顶点v
DeleteVex(&g,v);//在图中删除一个顶点v
Degree(g,v);//计算顶点v的度数
DFETraverse(g,v);//从顶点v出发对图进行深度优先遍历
BFSTraverse(g,v);//从顶点v出发对图进行广度优先遍历
}ADT Graph
#define _CRT_SECURE_NO_WARNINGS 1
#define MaxVex 20//预设最大顶点数
const int MAXINT = 0xfffffff;//最大整数,表示无穷大
typedef struct
{
VRType adj;//VRType为顶点关系类型,对无权图值为0或1
InfoType info;//该弧相关信息
}ArcBox;
typedef struct
{
VElemType vexs[MaxVex];//VElemType为顶点信息类型
ArcBox arcs[MaxVex][MaxVex];//邻接矩阵,即边表
int vexnum;//顶点数
int arcnum;//边数
int kind;//邻接矩阵的存储的图的种类:1有向图,2无向图,3有向网,4无向网
}MGraph;
class Graph
{
private:
MGraph mg;
public:
void CreateGraph();//创建图
int LocateVex(VElemType x);//返回图中顶点x在顶点数组中的下标
void CreateDG();//构造有向图
void CreateUDG();//构造无向图
void CreateDN();//构造有向网
void CreateUDN();//构造无向网
int DegreeGraph(VElemType x);//计算顶点的度数
void ShortPath_DIJ(VElemType v);//求最短路径
void Dispath(int dist[], int path[], int s[], VElemType x);//输出最短路径
void Floyd();//Floyd算法求最短路径
void Dispath(int dist[MaxVex][MaxVex]);//输出最短路径
};
void Graph::CreateGraph()
{
cout << "输入图的种类:1:有向图 2:无向图 3:有向网 4:无向网";
cin >> mg.kind;
switch (mg.kind)
{
case 1:CreateDG();//构造有向图
break;
case 2:CreateUDG();//构造无向图
break;
case 3:CreateDN();//构造有向网
break;
case 4:CreateUDN();//构造无向网
}
}
int Graph::LocateVex(VElemType x)
{
for (int i = 0; i < mg.vexnum; i++)
{
if (x == mg.vexs[i])
return i;
}
return -1;
}
void Graph::CreateDG()
{
int i, j, h, t;
VElemType u, v;
int flag;//0表示没有弧信息,1表示有弧信息
cin >> mg.vexnum >> mg.arcnum >> flag;
for (int i = 0; i < mg.vexnum; i++)
{
cin >> mg.vexs[i];//构造顶点信息
}
for (i = 0; i < mg.vexnum; i++)
{
for (j = 0; j < mg.vexnum; j++)
{
mg.arcs[i][j].adj = 0;//用0初始化邻接矩阵
mg.arcs[i][j].info = NULL;//用NULL初始化该弧的相关信息
}
}
for (i = 0; i < mg.arcnum; i++)
{
cin >> u >> v;
h = LocateVex(u);
t = LocateVex(v);
if (flag)
{
cin >> mg.arcs[h][t].info;
}
mg.arcs[h][t].adj = 1;//1表示顶点相邻
mg.arcs[t][h].adj = 1;//若为无向图加上这条
}
}
void Graph::CreateDN()
{
int i, j, h, t, w;
VElemType u, v;
int flag;//0表示没有弧信息,1表示有弧信息
cin >> mg.vexnum >> mg.arcnum >> flag;
for (int i = 0; i < mg.vexnum; i++)
{
cin >> mg.vexs[i];//构造顶点信息
}
for (i = 0; i < mg.vexnum; i++)
{
for (j = 0; j < mg.vexnum; j++)
{
if (i == j)
{
mg.arcs[i][j].adj = 0;//用0初始化邻接矩阵
}
else
{
mg.arcs[i][j].adj = MAXINT;
}
mg.arcs[i][j].info = NULL;//用NULL初始化该弧的相关信息
}
}
for (i = 0; i < mg.arcnum; i++)
{
cin >> u >> v >> w;
h = LocateVex(u);
t = LocateVex(v);
if (flag)
{
cin >> mg.arcs[h][t].info;
}
mg.arcs[h][t].adj = w;
mg.arcs[t][h].adj = w;//若为无向网加上该赋值
}
}
int Graph::DegreeGraph(VElemType x)
{
int h = LocateVex(x);
int count = 0;
for (int i = 0; i < mg.vexnum; i++)
{
if (mg.arcs[h][i].adj && mg.arcs[h][i].adj != MAXINT)
count++;
if (mg.arcs[i][h].adj && mg.arcs[i][h].adj != MAXINT)
count++;
}
return count;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;
typedef int VElemType;
typedef int VRType;
typedef int InfoType;
#define MaxVex 20//预设最大顶点数
const int MAXINT = 0xfffffff;//最大 整数,表示无穷大
typedef struct
{
VRType adj;//VRType为顶点关系类型,对无权图值为0或1
InfoType info;//该弧相关信息
}ArcBox;
typedef struct
{
VElemType vexs[MaxVex];//VElemType为顶点信息类型
ArcBox arcs[MaxVex][MaxVex];//邻接矩阵,即边表
int vexnum;//顶点数
int arcnum;//边数
int kind;//邻接矩阵的存储的图的种类:1有向图,2无向图,3有向网,4无向网
}MGraph;
class Graph
{
private:
MGraph mg;
public:
void CreateGraph();//创建图
int LocateVex(VElemType x);//返回图中顶点x在顶点数组中的下标
void CreateDG();//构造有向图
void CreateUDG();//构造无向图
void CreateDN();//构造有向网
void CreateUDN();//构造无向网
int DegreeGraph(VElemType x);//计算有向图顶点的度数
};
void Graph::CreateGraph()
{
cout << "输入图的种类:1:有向图 2:无向图 3:有向网 4:无向网"<<endl;
cout << "请输入:";
cin >> mg.kind;
switch (mg.kind)
{
case 1:CreateDG();//构造有向图
break;
case 2:CreateUDG();//构造无向图
break;
case 3:CreateDN();//构造有向网
break;
case 4:CreateUDN();//构造无向网
}
}
int Graph::LocateVex(VElemType x)
{
for (int i = 0; i < mg.vexnum; i++)
{
if (x == mg.vexs[i])
return i;
}
return -1;
}
void Graph::CreateDG()
{
int i, j, h, t;
VElemType u, v;
int flag;//0表示没有弧信息,1表示有弧信息
cout << "请输入顶点数、边数以及是否有弧信息(0/1)";
cin >> mg.vexnum >> mg.arcnum >> flag;
cout << "请输入" << mg.vexnum << "个顶点:";
for (int i = 0; i < mg.vexnum; i++)
{
cin >> mg.vexs[i];//构造顶点信息
}
for (i = 0; i < mg.vexnum; i++)
{
for (j = 0; j < mg.vexnum; j++)
{
mg.arcs[i][j].adj = 0;//用0初始化邻接矩阵
mg.arcs[i][j].info = NULL;//用NULL初始化该弧的相关信息
}
}
for (i = 0; i < mg.arcnum; i++)
{
cout << "请输入关联的两个顶点:";
cin >> u >> v;
h = LocateVex(u);
t = LocateVex(v);
if (flag)
{
cout << "请输入权值:";
cin >> mg.arcs[h][t].info;
}
mg.arcs[h][t].adj = 1;//1表示顶点相邻
}
}
int Graph::DegreeGraph(VElemType x)
{
int h = LocateVex(x);
int count = 0;
for (int i = 0; i < mg.vexnum; i++)
{
if (mg.arcs[h][i].adj && mg.arcs[h][i].adj != MAXINT)
count++;
if (mg.arcs[i][h].adj && mg.arcs[i][h].adj != MAXINT)
count++;
}
cout << "该顶点的度数为:" << count << endl;
return 0;
}
int main()
{
Graph a;
a.CreateGraph();
a.DegreeGraph(1);
a.DegreeGraph(2);
a.DegreeGraph(3);
a.DegreeGraph(4);
return 0;
}