一、创建
- 规范方式
#include<stdio.h>
#include<stdlib.h>
#define INIFINITE 32768
#define FALSE 0
#define TRUE 1
typedef int Vertex;
typedef int Boolean;
typedef char VertexType;
typedef int WeightType;
#define MaxVertexNum 10
typedef struct GNode *MGraph;
typedef struct GNode
{
VertexType data[MaxVertexNum];
WeightType weights[MaxVertexNum][MaxVertexNum];
int nv;
int ne;
} GNode;
typedef struct ENode *Edge;
typedef struct ENode
{
Vertex v1, v2;
WeightType weight;
} ENode;
MGraph InitGraph(int vertexNum)
{
MGraph G = (MGraph)malloc(sizeof(GNode));
G->nv = vertexNum;
G->ne = 0;
Vertex v, w;
for(v = 0; v < G->nv; v++)
{
for(w = 0; w < G->nv; w++)
G->weights[v][w] = INIFINITE;
}
return G;
}
void Insert(MGraph G, Edge E)
{
G->weights[E->v1][E->v2] = E->weight;
}
MGraph BuildGraph()
{
int nv;
scanf("%d", &nv);
MGraph G = InitGraph(nv);
scanf("%d", &G->ne);
if(G->ne != 0)
{
for(Vertex v = 0; v < G->ne; v++)
{
Edge E = (Edge)malloc(sizeof(ENode));
scanf("%d %d %d", &E->v1, &E->v2, &E->weight);
Insert(G, E);
}
}
return G;
}
- 简洁方式
int weights[MaxVertexNum][MaxVertexNum];
int nv, ne;
void BuildMGraph()
{
int v, w, v1, v2, weight;
scanf("%d", &nv);
for(v = 0; v < nv; v++)
{
for(w = 0; w < nv; w++)
weights[v][w] = v == w ? 0 : INIFINITY;
}
scanf("%d ", &ne);
for(int i = 0; i < ne; i++)
{
scanf("%d %d %d", &v1, &v2, &weight);
weights[v1][v2] = weight;
weights[v2][v1] = weight;
}
}
二、遍历
- BFS
Vertex data[MaxVertexNum];
int front = 0, rear = 0;
Boolean visited[MaxVertexNum];
void BFS(MGraph G)
{
Vertex v;
for(v = 0; v < G->nv; v++)
visited[v] = FALSE;
for(v = 0; v < G->nv; v++)
{
if(!visited[v])
{
rear = (rear + 1) % MaxVertexNum;
data[rear] = v;
printf("%c ", G->data[v]);
visited[v] = TRUE;
int i, j;
while(front != rear)
{
front = (front + 1) % MaxVertexNum;
i = data[front];
for(j = 0; j < G->nv; j++)
if(G->weights[i][j] != INIFINITE && !visited[j])
{
visited[j] = TRUE;
printf("%c ", G->data[j]);
rear = (rear + 1) % MaxVertexNum;
data[rear] = j;
}
}
}
}
}
- DFS
void DFS(MGraph G, Vertex v){
visited[v] = TRUE;
printf("%c ", G->data[v]);
Vertex w;
for(w = 0; w < G->nv; w++)
if(!visited[w])
DFS(G, w);
}
void DFSTraverse(MGraph G){
Vertex v;
for(v = 0; v < G->nv; v++)
visited[v] = FALSE;
for(v = 0; v < G->nv; v++)
if(!visited[v])
DFS(G, v);
}
三、最短路径
单源最短路径——无权图
int dist[MaxVertexNum];
int path[MaxVertexNum];
Vertex data[MaxVertexNum];
int front = 0, rear = 0;
void ShortestPath(MGraph G, Vertex v){
Vertex w = 0;
for(; w < G->nv; w++){
dist[w] = -1;
path[w] = -1;
}
dist[v] = 0;
rear = (rear + 1) % MaxVertexNum;
data[rear] = v;
while(front != rear){
front = (front + 1) % MaxVertexNum;
v = data[front];
for(w = 0; w < G->nv; w++){
if(G->weights[v][w] != INIFINITE && dist[w] == -1){
dist[w] = dist[v] + 1;
path[w] = v;
rear = (rear + 1) % MaxVertexNum;
data[rear] = w;
}
}
}
}
单源最短路径——有权图(Dijkstra算法)
int dist[MaxVertexNum];
int path[MaxVertexNum];
int set[MaxVertexNum];
void Dijkstra(int v)
{
int w = 0;
//初始化
for(; w < nv; w++)
{
dist[w] = weights[v][w];
if(weights[v][w] < INIFINITY)
path[w] = v;
else
path[w] = -1;
set[w] = 0;
}
path[v] = -1;
set[v] = 1;
//进入循环,选取最小值,更新set , dist, path,数组
int min;
int minIndex;
while(1)
{
//从未收入的顶点中选取最小值
for(w = 0; w < nv; w++)
if(!set[w]){
min = w;
break;
}
for(w = 0; w < nv; w++){
if(!set[w])
min = dist[w] < dist[min] ? w : min;
}
min = INIFINITY;
for(w = 0; w < nv; w++)
{
if(!set[w] && dist[w] < min)
{
min = dist[w];
minIndex = w;
}
}
//更新set
set[minIndex] = 1;
//检查是否存在未被收入的顶点
for(w = 0; w < nv; w++)
if(!set[w])
break;
//顶点全部收入,结束循环
if(w == nv)
break;
for(w = 0; w < nv; w++)
{
if(!set[w] && weights[minIndex][w] < INIFINITY && dist[w] > dist[minIndex] + weights[minIndex][w])
{
dist[w] = dist[minIndex] + weights[minIndex][w];
path[w] = minIndex;
}
}
}
}
//借助堆栈打印路径
void PrintPath(int v)
{
int stack[MaxVertexNum];
int top = -1;
while(path[v] != -1)
{
stack[++top] = v;
v = path[v];
}
stack[++top] = v;
while(top != -1)
{
printf("%d ", stack[top--]);
}
printf("\n");
}
多源最短路径——Floyd算法(待补)