邻接表:
代码:(理解了一遍)
数组(静态链表)
#include <iostream>
#inclue <cstring>
#include <algorithm>
using namespace std;
const int N=10010,M=N*2;
//因为有N个头节点所以定义N个数组,单链表可以直接int h
int h[N],e[M],ne[M],idx;
void add(int a,int b){
//插入操作即在h[a]头结点后插入节点b
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int main(){
//初始化让所有的头结点指向空节点(下标为-1)
memset(h,-1,sizeof h);
}
结构体:
#define MaxVertexNum 100
typedef char vertexType ;//顶点中存字符类型数据
/*边表节点*/
typedef struct ArcNode{
int adjvex;//弧指向的顶点下标
struct ArcNode *next;//指向下一条弧的指针
}ArcNode;
/*顶点表节点*/
typedef struct VNode {
vertexType data;//顶点信息(char)
ArcNode* first;//指向第一个依附该顶点的弧的指针
}VNode,AdjList[MaxVertexNum];
/*图*/
typedef struct {
AdjList vertices;
int vecnum, arcnum;
}ALGraph;
void create(ALGraph *G) {
cout << "-----------------------------------------------------" << endl;
cout << "请输入顶点数和边数" << endl;
cin >> G->vecnum >> G->arcnum;
cout << "请输入顶点" << endl;
for (int i = 0; i < G->vecnum; i++) {
cin >> G->vertices[i].data;
G->vertices[i].first = NULL;
}
cout << "请输入边(Vi,Vj)的下标i,j"<<endl;
int i, j;
ArcNode* p;
for (int k = 0; k < G->arcnum; k++) {
cin>>i>>j;
p = (ArcNode*)malloc(sizeof(ArcNode));//创建新的边表结点
//adjvex弧指向节点的下标
p->adjvex = j;
//p->next是指向下一条弧的指针
p->next = G->vertices[i].first;//头插法
//该顶点依附的第一条边就是p
G->vertices[i].first = p;
/*如果是无向图还应该加入下面这一段*/
p = (ArcNode*)malloc(sizeof(ArcNode));
//adjvex弧指向节点的下标
p->adjvex = i;
p->next = G->vertices[j].first;
G->vertices[j].first = p;
}
cout << "邻接表如下:" << endl;
//vecnum顶点的个数
for (int i = 0; i < G->vecnum; i++) {
//p是边表节点
p = G->vertices[i].first;
while (p)
{
cout <<"<"<< G->vertices[i].data << ","<<G->vertices[p->adjvex].data<<"> ";
//p->next是指向下一条弧的指针
p = p->next;
}
cout << endl;
}
cout << "-----------------------------------------------------" << endl;
}
int main()
{
ALGraph G;
create(&G);
}
邻接矩阵
代码:
//邻接矩阵
#include<stdio.h>
#include<stdlib.h>
#define Status int
#define OVERFLOW -2
#define OK 1
#define ERROR -1
//邻阶矩阵
#define MaxInt 32767
#define MVNum 100
typedef char VerTexType;//顶点的数据类型
typedef int ArcType;//边的权值类型
typedef struct
{
VerTexType vexs[MVNum];//顶点表
ArcType arcs[MVNum][MVNum];//邻阶矩阵
int vexnum,arcnum;//图当前的点数和边数
}AMGraph;
int LocateVex(AMGraph &G,char v)
{
for(int i=0;i<G.vexnum;i++)
{
if(v==G.vexs[i])
return i;
}
}
Status CreateUDN(AMGraph &G)
{
char v1,v2;int w;int j;
scanf("%d %d",&G.vexnum,&G.arcnum);//输入总顶点数,总边数
for(int i=0;i<G.vexnum;++i)
{
scanf(" %c",&G.vexs[i]);//printf("bbb\n");
}
for(i=0;i<G.vexnum;++i)//初始化邻阶矩阵,边的权值均置为极大值MaxInt
{
for(j=0;j<G.vexnum;++j)
{
G.arcs[i][j]=MaxInt;//printf("aaa\n");
}
}
for(int k=0;k<G.arcnum;++k)//构造邻阶矩阵
{
scanf(" %c %c %d",&v1,&v2,&w);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j]=w;
G.arcs[j][i]=G.arcs[i][j];
}
return OK;
}
int main()
{
AMGraph G;
CreateUDN(G);
printf("%d\n",G.arcs[1][2]);//为测试而输出
return 0;
}
Floyd算法基于邻接矩阵:
详细题解:
https://blog.csdn.net/qq_52934831/article/details/120013082
代码:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
#define INFINITY 65535//无边时的权值
#define MAX_VERTEX_NUM 10//最大顶点数
typedef struct MGraph{
string vexs[10];//顶点信息
int arcs[10][10];//邻接矩阵
int vexnum, arcnum;//顶点数和边数
}MGraph;
int LocateVex(MGraph G, string u)//返回顶点u在图中的位置
{
for(int i=0; i<G.vexnum; i++)
if(G.vexs[i]==u)
return i;
return -1;
}
void CreateDN(MGraph &G)//构造有向网
{
string v1, v2;
int w;
int i, j, k;
cout<<"请输入顶点数和边数:";
cin>>G.vexnum>>G.arcnum;
cout<<"请输入顶点:";
for(i=0; i<G.vexnum; i++)
cin>>G.vexs[i];
for(i=0; i<G.vexnum; i++)
for(j=0; j<G.vexnum; j++)
G.arcs[i][j]=INFINITY;
cout<<"请输入边和权值:"<<endl;
for(k=0; k<G.arcnum; k++)
{
cin>>v1>>v2>>w;
i=LocateVex(G, v1);
j=LocateVex(G, v2);
G.arcs[i][j]=w;
}
}
//迪杰斯特拉算法求有向网G的v0顶点到其余顶点v的最短路径p[v]及带权长度D[v]
//p[][]=-1表示没有路径,p[v][i]存的是从v0到v当前求得的最短路径经过的第i+1个顶点(这是打印最短路径的关键),则v0到v的最短路径即为p[v][0]到p[v][j]直到p[v][j]=-1,路径打印完毕。
//final[v]为true当且仅当v∈S,即已经求得从v0到v的最短路径。
void ShortestPath_DIJ(MGraph G, int v0, int p[][MAX_VERTEX_NUM], int D[])
{
int v, w, i, j, min;
bool final[10];
for(v=0; v<G.vexnum; v++)
{
final[v]=false;//设初值
D[v]=G.arcs[v0][v];//D[]存放v0到v得最短距离,初值为v0到v的直接距离
for(w=0; w<G.vexnum; w++)
p[v][w]=-1;//设p[][]初值为-1,即没有路径
if(D[v]<INFINITY)//v0到v有直接路径
{
p[v][0]=v0;//v0到v最短路径经过的第一个顶点
p[v][1]=v;//v0到v最短路径经过的第二个顶点
}
}
D[v0]=0;//v0到v0距离为0
final[v0]=true;//v0顶点并入S集
for(i=1; i<G.vexnum; i++)//其余G.vexnum-1个顶点
{//开始主循环,每次求得v0到某个顶点v的最短路径,并将v并入S集,然后更新p和D
min=INFINITY;
for(w=0; w<G.vexnum; w++)//对所有顶点检查
if(!final[w] && D[w]<min)//在S集之外(即final[]=false)的顶点中找离v0最近的顶点,将其赋给v,距离赋给min
{
v=w;
min=D[w];
}
final[v]=true;//v并入S集
for(w=0; w<G.vexnum; w++)//根据新并入的顶点,更新不在S集的顶点到v0的距离和路径数组
{
if(!final[w] && min<INFINITY && G.arcs[v][w]<INFINITY && (min+G.arcs[v][w]<D[w]))
{//w不属于S集且v0->v->w的距离<目前v0->w的距离
D[w]=min+G.arcs[v][w];//更新D[w]
for(j=0; j<G.vexnum; j++)//修改p[w],v0到w经过的顶点包括v0到v经过的所有顶点再加上顶点w
{
p[w][j]=p[v][j];
if(p[w][j]==-1)//在p[w][]第一个等于-1的地方加上顶点w
{
p[w][j]=w;
break;
}
}
}
}
}
}
void main()
{
int i, j;
MGraph g;
CreateDN(g);
int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//最短路径数组p
int D[MAX_VERTEX_NUM];//最短距离数组D
ShortestPath_DIJ(g, 0, p, D);
cout<<"最短路径数组p[i][j]如下:"<<endl;
for(i=0; i<g.vexnum; i++)
{
for(j=0; j<g.vexnum; j++)
cout<<setw(3)<<p[i][j]<<" ";
cout<<endl;
}
cout<<g.vexs[0]<<"到各顶点的最短路径及长度为:"<<endl;
for(i=0; i<g.vexnum; i++)
{
if(i!=0 && D[i]!=INFINITY)
{
cout<<g.vexs[0]<<"-"<<g.vexs[i]<<"的最短路径长度为:"<<D[i];
cout<<" 最短路径为:";
for(j=0; j<g.vexnum; j++)
{
if(p[i][j]>-1)
cout<<g.vexs[p[i][j]]<<" ";
}
cout<<endl;
}
else if(D[i]==INFINITY)
cout<<g.vexs[0]<<"-"<<g.vexs[i]<<":"<<"不可达"<<endl;
}
}