本例图的画法:
运行结果:
源文件:
#include "邻接表宽度优先遍历的queue.h"
Status Init(LGraph* lg, int nSize)
{
int i;
lg->numofDot = nSize;
lg->numofEdge = 0;
lg->a = (ENode**)malloc(nSize * sizeof(ENode*));
if (!lg->a)
{
return ERROR;
}
else
{
for (i = 0; i < lg->numofDot; i++)
lg->a[i] = NULL;
return OK;
}
}
void Destroy(LGraph* lg)
{
int i;
ENode* p, * q;
for (i = 0; i < lg->numofDot; i++)
{
p = lg->a[i];
q = p;
while (p)
{
p = p->nextArc;
free(q);
q = p;
}
}
free(lg->a);
}
Status Exist(LGraph* lg, int u, int v)
{
ENode* p;
if (u<0 || v<0 || u>lg->numofDot - 1 || v>lg->numofDot - 1 || u == v)
{
return ERROR;
}
p = lg->a[u];
while (p && p->adjVex != v)
{
p = p->nextArc;
}
if (!p)
{
return ERROR;
}
else
{
return OK;
}
}
Status Insert(LGraph* lg, int u, int v, ElemType w)
{
ENode* p;
if (u<0 || v<0 || u>lg->numofDot - 1 || v>lg->numofDot - 1 || u == v)
return ERROR;
if (Exist(lg, u, v))
{
return Duplicate;
}
p = (ENode*)malloc(sizeof(ENode));
p->adjVex = v;
p->w = w;
p->nextArc = NULL;
p->nextArc = lg->a[u];
lg->a[u] = p;
lg->numofEdge++;
return OK;
}
Status Remove(LGraph* lg, int u, int v)
{
ENode* p, * q;
if (u<0 || v<0 || u>lg->numofDot - 1 || v>lg->numofDot - 1 || u == v)
return ERROR;
p = lg->a[u], q = NULL;
while (p && p->adjVex != v)
{
q = p;
p = p->nextArc;
}
if (!p)
return NotPresent;
if (q)
q->nextArc = p->nextArc;
free(p);
lg->numofEdge--;
return OK;
}
void DFS(int v, int visited[], LGraph g)
{
ENode* w;
printf("%d ", v);
visited[v] = 1;
for (w = g.a[v]; w; w = w->nextArc)
{
if (!visited[w->adjVex])
DFS(w->adjVex, visited, g);
}
}
void DFSGraph(LGraph g)
{
int i;
int* visited = (int*)malloc(g.numofDot * sizeof(int));
for (i = 0; i < g.numofDot; i++)
{
visited[i] = 0;
}
for (i = 0; i < g.numofDot; i++)
{
if (!visited[i])
{
DFS(i, visited, g);
}
}
free(visited);
}
void BFS(int v, int visited[], LGraph g)
{
ENode* w;
Queue q;
queuecreate(&q, g.numofDot);
visited[v] = 1;
printf("%d ", v);
EnQueue(&q, v);
while (!queueIsEmpty(&q))
{
queueFront(&q, &v);
DeQueue(&q);
for (w = g.a[v]; w; w = w->nextArc)
{
if (!visited[w->adjVex])
{
visited[w->adjVex] = 1;
printf("%d ", w->adjVex);
EnQueue(&q, w->adjVex);
}
}
}
}
void BFSGrapg(LGraph g)
{
int i;
int* visited = (int*)malloc(g.numofDot * sizeof(int));
for (i = 0; i < g.numofDot; i++)
{
visited[i] = 0;
}
for (i = 0; i < g.numofDot; i++)
{
if (!visited[i])
{
BFS(i, visited, g);
}
}
free(visited);
}
void dijkstra(LGraph lg)
{
ENode* p;
int i, j, min, index;
double allLength = 0;
double* ahead = (double*)malloc(lg.numofDot * sizeof(double));
double* after = (double*)malloc(lg.numofDot * sizeof(double));
int u;
printf("请输入起点u = \t");
scanf_s("%d", &u);
for (i = 0; i < lg.numofDot; i++)
{
ahead[i] = INF;
after[i] = INF;
}
for (p = lg.a[u]; p; p = p->nextArc)
{
if (p != NULL)
{
after[p->adjVex] = p->w;
}
}
for (int n = 1; n < lg.numofDot; n++)
{
min = INF;
for (i = 0; i < lg.numofDot; i++)
{
if (min > after[i] && after[i] != -1&&i!=u)
{
min = after[i];
}
}
for (index = 0; index < lg.numofDot; index++)
{
if (index == u)
continue;
if (after[index] == min)
break;
}
ahead[index] = min;
after[index] = -1;
while (lg.a[index])
{
if (after[lg.a[index]->adjVex] > ahead[index] + lg.a[index]->w)
{
after[lg.a[index]->adjVex] = ahead[index] + lg.a[index]->w;
}
lg.a[index] = lg.a[index]->nextArc;
}
}
for (i = 0; i < lg.numofDot; i++)
{
if (i != u)
{
if (ahead[i] != INF)
{
printf("\n起点到%d的距离为:%lf", i, ahead[i]);
allLength += ahead[i];
}
else
{
printf("\n起点到%d的距离为:∞", i);
}
}
}
printf("\n由此点出发去各地的最短总路径为: %lf", allLength);
free(ahead);
free(after);
}
void main()
{
LGraph lg;
int nSize, nEdge;
int u, v, w;
int judge = 0;
printf("请输入图的总结点数:\t");
scanf_s("%d", &nSize);
printf("请输入图的总边数:\t");
scanf_s("%d", &nEdge);
Init(&lg, nSize);
for (int i = 0; i < nEdge; i++)
{
printf("请输入边的指向(u->v)和权重,格式: u v w :\t");
scanf_s("%d %d %d", &u, &v, &w);
int judge = Insert(&lg, u, v, w);
switch (judge)
{
case 0:
printf("\n输入的u或v有问题,插入失败,请重试");
break;
case 5:
printf("\n此边已存在,插入失败,请重试");
break;
default:
break;
}
}
printf("\n邻接表的深度优先遍历为:\n");
DFSGraph(lg);
printf("\n邻接表的宽度优先遍历为:\n");
BFSGrapg(lg);
dijkstra(lg);
}
邻接表宽度优先遍历的queue.h
#pragma once
#include "邻接表的基础结构.h"
typedef struct Queue
{
int front;
int rear;
int maxSize;
int* element;
}Queue;
void queuecreate(Queue* Q, int mSize)
{
Q->maxSize = mSize;
Q->element = (int*)malloc(sizeof(int) * mSize);
Q->front = Q->rear = 0;
}
void queueDestory(Queue* Q)
{
Q->maxSize = 0;
Q->front = Q->rear = -1;
free(Q->element);
}
BOOL queueIsEmpty(Queue* Q)
{
return Q->front == Q->rear;
}
BOOL queueIsFull(Queue* Q)
{
return (Q->rear + 1) % Q->maxSize == Q->front;
}
BOOL queueFront(Queue* Q, int* x)
{
if (queueIsEmpty(Q))
return false;
*x = Q->element[(Q->front + 1) % Q->maxSize];
return true;
}
BOOL EnQueue(Queue* Q, int x)
{
if (queueIsFull(Q))
return false;
Q->rear = (Q->rear + 1) % Q->maxSize;
Q->element[Q->rear] = x;
return true;
}
BOOL DeQueue(Queue* Q)
{
if (queueIsEmpty(Q))
return false;
Q->front = (Q->front + 1) % Q->maxSize;
return true;
}
void queueClear(Queue* Q)
{
Q->front = Q->rear = 0;
}
邻接表的基础结构.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define ERROR 0 ;
#define OK 1;
#define Overflow 2;
#define Underflow 3;
#define NotPresent 4;
#define Duplicate 5;
typedef int Status;
typedef double ElemType;
typedef bool BOOL;
#define INF 2147483647
typedef struct eNode
{
int adjVex;
ElemType w;
struct eNode* nextArc;
}ENode;
typedef struct lGraph
{
int numofDot;
int numofEdge;
ENode** a;
}LGraph;