新人第一次发,可能有错,请大佬们多多包涵
一、邻接矩阵(Adjacency Matrix)
1.基本介绍
言简意赅,邻接矩阵时就是表示顶点间相邻关系的矩阵!
我认为,邻接矩阵可以分为三种:
1.无向无权邻接矩阵 A[i][j]= 1(若i,j相邻)并且A[j][i]=1 or 0(不相邻)
2.有向无权邻接矩阵 A[i][j]= 1(若i,j相邻) or 0(不相邻)
3.有向有权邻接矩阵。 A[i][j]= 权值(若i,j相邻) or 0(不相邻)
2.代码解释——注意在这里我们构建的是无向无边邻接矩阵
1.邻接矩阵类型的结构体建立
在这里,我们定义了 ADJ_MATRIX
1.邻接矩阵的 顶点数量(vexnum),边(弧)的数量(arcnum)。
2.顶点的内容——构建了一个内容数组(vexs[ ])。
3.展现弧关系的矩阵——构建了一个弧关系二维数组arcs[ ][ ]。
const int MAXLEN=100;
typedef char VEXTYPE;
typedef int ARCTYPE;
//构建邻接矩阵
struct ADJ_MATRIX
{
int vexnum,arcnum; //点数和弧数
VEXTYPE vexs[MAXLEN]; //顶点内容 的数组(这里是字符型)
ARCTYPE arcs[MAXLEN][MAXLEN]; //表示弧关系的矩阵
};
2.定义构造邻接矩阵 的函数
第一步:为表示邻接矩阵类型的结构体分配空间。
第二步:输入顶点数(vexnum)和弧数(arcnum)。
第三步:给顶点数组赋值(顶点的内容是什么),注意这里是字符型的。
第四步:初始化弧关系二维数组,让他们的值都为零。
第五步:输入边(i,j)——确定顶点之间的关系。
//直接创建邻接矩阵
ADJ_MATRIX* Create_Matrix()
{
ADJ_MATRIX* matrix_graph;
//1.分配空间
matrix_graph = new ADJ_MATRIX;
//2.输入顶点数vexnum,弧数arcnum
cin>>matrix_graph->vexnum>>matrix_graph->arcnum;
//!!!!!3.为顶点内容(vexs[i])赋值
for(int i=0;i<matrix_graph->vexnum;i++)
cin>>matrix_graph->vexs[i];//char
/*
vexs[i] a b c d e
下标 0 1 2 3 4
*/
//4.初始化邻接矩阵
for(int i=0;i<matrix_graph->vexnum;i++)
for(int j=0;j<matrix_graph->vexnum;j++)
matrix_graph->arcs[i][j]=0;
//5.输入弧——确定顶点之间的关系
for(int i=0;i<matrix_graph->arcnum;i++)
{
int x,y;
cin>>x>>y;//输入有联系顶点的下标
matrix_graph->arcs[x][y]=1;
matrix_graph->arcs[y][x]=1;
}
return matrix_graph;
}
3.邻接矩阵的输出——不多说,直接上代码
//输出邻接矩阵
void Print_ADJ_Matrix(ADJ_MATRIX* matrix_graph)
{
//在最上方展示顶点内容
cout<<" ";
for(int i=0;i<matrix_graph->vexnum;i++)
cout<<char(matrix_graph->vexs[i])<<" ";
cout<<endl;
for(int i=0;i<matrix_graph->vexnum;i++)
{
cout<<matrix_graph->vexs[i]<<" ";//在最左侧展示顶点内容
for(int j=0;j<matrix_graph->vexnum;j++)
cout<<matrix_graph->arcs[i][j]<<" ";
cout<<endl;
}
}
4.(展示)main函数运行与运行案例
int main()
{
ADJ_MATRIX* M_g; //定义一个ADJ_MATRIX的指针对象——M_g
M_g=Create_Matrix(); //2.创建
Print_ADJ_Matrix(M_g); //3.打印
return 0; //注意习惯
}
**********************************************运行——输入*************************************************
5 5
a b c d e
0 1
1 2
2 3
3 4
1 4
**********************************************运行——输出*************************************************
二、邻接表 (Adjacency List)
1.基本介绍
一种链式存储方法,对于图中每个顶点vi建立一个单链表,将与vi相连的顶点放在这个链表中。二每一个单链表有边节点和表头结点组成。
vex_data | firstarc |
vex_data | info | nextarc |
2.代码解释——在这里我们构建的是无向无权邻接表
1.邻接矩阵类型(无向图)的结构体建立
我们定义了 ADJ_LIST
1.邻接表的 顶点数量(vexnum),边(弧)的数量(arcnum)。
2.邻接表 adjlist[ ] (每个顶点相连关系的链表)
(1) VEXNODE
[1] vex_data——数据域
[2] firstarc——链域
(2) ARCNODE
[1] vex_data——临界点域
[2] info——数据域 在这里,我们默认为0。
[3] nextarc——链域
const int MAXLEN=100;
typedef char VEXTYPE;
typedef int ARCTYPE;
//邻(lin)接表的边结点
struct ARCNODE
{
VEXTYPE vex_data; //顶点的值
int info; //与边相关的信息,如权值
ARCNODE* nextarc;
};
//邻接表的表头结点
struct VEXNODE
{
VEXTYPE vex_data;
ARCNODE* firstarc;
};
//构建邻接表
struct ADJ_LIST
{
int vexnum,arcnum;
VEXNODE adjlist[MAXLEN]; //每个点的邻接链表构成的数组adjlist
}
2.定义构造邻接表 的函数
第一步:为表示邻接表类型的结构体分配空间。
第二步:输入顶点数(vexnum)和弧数(arcnum)。
第三步:给顶点数组赋值(顶点的内容是什么),注意这里是字符型的。
第四步:输入边(i,j)——确定顶点之间的关系。由于这里是无向图,所有要操作两次
ADJ_LIST* Create_List()
{
ADJ_LIST* list_graph;
ARCNODE* p;
//1.list_graph开辟空间
list_graph=new ADJ_LIST;
//2.输入点数,边数
cin>>list_graph->vexnum>>list_graph->arcnum;
//3.为顶点内容赋值(adjlist[i].vex_data)并进行初始化
for(int i=0;i<list_graph->vexnum;i++)
{
cin>>list_graph->adjlist[i].vex_data;
list_graph->adjlist[i].firstarc=NULL;
}
//4.根据边的关系建表
for(int i=0;i<list_graph->arcnum;i++)
{
int x,y;
cin>>x>>y;
//(1)在下标x的链表上插入y的内容
p=new ARCNODE;
p->vex_data=list_graph->adjlist[y].vex_data;
p->nextarc=list_graph->adjlist[x].firstarc;
list_graph->adjlist[x].firstarc=p;
//(2)在下标y的链表上插入x的内容
p=new ARCNODE;
p->vex_data=list_graph->adjlist[x].vex_data;
p->nextarc=list_graph->adjlist[y].firstarc;
list_graph->adjlist[y].firstarc=p;
}
return list_graph;
}
3.邻接表的输出——不多说,直接上代码
void Print_ADJ_List(ADJ_LIST *list_graph)
{
ARCNODE* p;
for(int i=0;i<list_graph->vexnum;i++)
{
cout<<"<"<<i<<"> "<<list_graph->adjlist[i].vex_data;
p=list_graph->adjlist[i].firstarc;
while(p)
{
cout<<"->"<<p->vex_data;
p=p->nextarc;
}
cout<<"->^"<<endl;
}
}
4.(展示)main函数运行与运行案例
int main()
{
ADJ_LIST* L_graph; //定义ADJ_LIST
L_graph=Create_List(); //创建
Print_ADJ_List(L_graph); //输出
return 0;
}
**********************************************运行——输入*************************************************
5 5
a b c d e
0 1
1 2
2 3
3 4
1 4
**********************************************运行——输出*************************************************
细心的同学应该观察到这就是有上面矩阵的案例转变而来的
3.邻接矩阵转邻接表
//邻接矩阵转邻接表
ADJ_LIST* Matrix_To_List(ADJ_MATRIX* matrix_graph) {
ADJ_LIST* list_graph;
ARCNODE *p;
//1.分配空间
list_graph = new ADJ_LIST;
//2.给邻接表赋顶点数vexnum,弧数arcnum
list_graph->vexnum = matrix_graph->vexnum;
list_graph->arcnum = matrix_graph->arcnum;
//3.构建邻接表(邻接链表的数组)
for (int i = 0; i < list_graph->vexnum; i++) {
//初始化顶点i的一支单链表
list_graph->adjlist[i].vex_data = matrix_graph->vexs[i];
list_graph->adjlist[i].firstarc = NULL;
//对于除了i的顶点进行遍历.
for (int j = 0; j < list_graph->vexnum; j++) {
//注意:是头插法!!!
if (matrix_graph->arcs[i][j]) { //若有i和j联系(matrix_graph[i][j])则插入j
p = new ARCNODE;
p->vex_data = matrix_graph->vexs[j];
p->nextarc = list_graph->adjlist[i].firstarc;
list_graph->adjlist[i].firstarc = p;
}
}
}
return list_graph;
}
(展示)main函数运行与运行案例
int main() {
ADJ_MATRIX* M_g;
ADJ_LIST* L_g;
M_g =Create_Matrix();
Print_ADJ_Matrix(M_g);
L_g=Matrix_To_List(M_g);
Print_ADJ_List(L_g);
return 0;
}
**********************************************运行——输入*************************************************
5 5
a b c d e
0 1
1 2
2 3
3 4
1 4
**********************************************运行——输出*************************************************
三.最后给大家一个最终的源代码内容,可以在电脑上试着自己运行
#include<iostream>
using namespace std;
const int MAXLEN = 100;
typedef char VEXTYPE;
typedef int ARCTYPE;
//构建邻接矩阵
struct ADJ_MATRIX {
int vexnum, arcnum; //点数和弧数
VEXTYPE vexs[MAXLEN]; //顶点内容 的数组(这里是字符型)
ARCTYPE arcs[MAXLEN][MAXLEN]; //表示弧关系的矩阵
};
//邻(lin)接表的边结点
struct ARCNODE {
VEXTYPE vex_data; //顶点的值
int info = 0; //与边相关的信息,如权值
ARCNODE* nextarc;
};
//邻接表的表头结点
struct VEXNODE {
VEXTYPE vex_data;
ARCNODE* firstarc;
};
//构建邻接表
struct ADJ_LIST {
int vexnum, arcnum;
VEXNODE adjlist[MAXLEN]; //每个点的邻接链表构成的数组adjlist
};
//直接创建邻接矩阵
ADJ_MATRIX* Create_Matrix() {
ADJ_MATRIX* matrix_graph;
//1.分配空间
matrix_graph = new ADJ_MATRIX;
//2.输入顶点数vexnum,弧数arcnum
cin >> matrix_graph->vexnum >> matrix_graph->arcnum;
//!!!!!3.为顶点内容(vexs[i])赋值
for (int i = 0; i < matrix_graph->vexnum; i++)
cin >> matrix_graph->vexs[i]; //char
/*
vexs[i] a b c d e
下标 0 1 2 3 4
*/
//4.初始化邻接矩阵
for (int i = 0; i < matrix_graph->vexnum; i++)
for (int j = 0; j < matrix_graph->vexnum; j++)
matrix_graph->arcs[i][j] = 0;
//5.输入弧——确定顶点之间的关系
for (int i = 0; i < matrix_graph->arcnum; i++) {
int x, y;
cin >> x >> y; //输入有联系顶点的下标
matrix_graph->arcs[x][y] = 1;
matrix_graph->arcs[y][x] = 1;
}
return matrix_graph;
}
//直接创建邻接表
ADJ_LIST* Create_List() {
ADJ_LIST* list_graph;
ARCNODE* p;
//1.list_graph开辟空间
list_graph = new ADJ_LIST;
//2.输入点数,边数
cin >> list_graph->vexnum >> list_graph->arcnum;
//3.为顶点内容赋值(adjlist[i].vex_data)并进行初始化
for (int i = 0; i < list_graph->vexnum; i++) {
cin >> list_graph->adjlist[i].vex_data;
list_graph->adjlist[i].firstarc = NULL;
}
//4.根据边的关系建表
for (int i = 0; i < list_graph->arcnum; i++) {
int x, y;
cin >> x >> y;
//(1)在下标x的链表上插入y的内容
p = new ARCNODE;
p->vex_data = list_graph->adjlist[y].vex_data;
p->nextarc = list_graph->adjlist[x].firstarc;
list_graph->adjlist[x].firstarc = p;
//(2)在下标y的链表上插入x的内容
p = new ARCNODE;
p->vex_data = list_graph->adjlist[x].vex_data;
p->nextarc = list_graph->adjlist[y].firstarc;
list_graph->adjlist[y].firstarc = p;
}
return list_graph;
}
//输出邻接矩阵
void Print_ADJ_Matrix(ADJ_MATRIX* matrix_graph)
{
//在最上方展示顶点内容
cout<<" ";
for(int i=0;i<matrix_graph->vexnum;i++)
cout<<char(matrix_graph->vexs[i])<<" ";
cout<<endl;
for(int i=0;i<matrix_graph->vexnum;i++)
{
cout<<char(matrix_graph->vexs[i])<<" ";//在最左侧展示顶点内容
for(int j=0;j<matrix_graph->vexnum;j++)
cout<<matrix_graph->arcs[i][j]<<" ";
cout<<endl;
}
}
//输出邻接表
void Print_ADJ_List(ADJ_LIST *list_graph) {
ARCNODE* p;
for (int i = 0; i < list_graph->vexnum; i++) {
cout << "<" << i << "> " << list_graph->adjlist[i].vex_data;
p = list_graph->adjlist[i].firstarc;
while (p) {
cout << "->" << p->vex_data;
p = p->nextarc;
}
cout << "->^" << endl;
}
}
//邻接矩阵转邻接表
ADJ_LIST* Matrix_To_List(ADJ_MATRIX* matrix_graph) {
ADJ_LIST* list_graph;
ARCNODE *p;
//1.分配空间
list_graph = new ADJ_LIST;
//2.给邻接表赋顶点数vexnum,弧数arcnum
list_graph->vexnum = matrix_graph->vexnum;
list_graph->arcnum = matrix_graph->arcnum;
//3.构建邻接表(邻接链表的数组)
for (int i = 0; i < list_graph->vexnum; i++) {
//初始化顶点i的一支单链表
list_graph->adjlist[i].vex_data = matrix_graph->vexs[i];
list_graph->adjlist[i].firstarc = NULL;
//对于除了i的顶点进行遍历.
for (int j = 0; j < list_graph->vexnum; j++) {
//注意:是头插法!!!
if (matrix_graph->arcs[i][j]) { //若有i和j联系(matrix_graph[i][j])则插入j
p = new ARCNODE;
p->vex_data = matrix_graph->vexs[j];
p->nextarc = list_graph->adjlist[i].firstarc;
list_graph->adjlist[i].firstarc = p;
}
}
}
return list_graph;
}