博客
关于我
数据结构 实验四(图中两点间所有路径)
阅读量:338 次
发布时间:2019-03-04

本文共 4875 字,大约阅读时间需要 16 分钟。

邻接表是一种高效的数据存储方式,常用于表示图的结构。以下是使用邻接表存储点和边的代码示例,以及如何输出两点间所有路径的实现:

邻接表的实现代码

#include 
#include
using namespace std;
#define VEX_MAXNUM 20
#define STACK_H_INCLUDED
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
typedef struct SqStack {
int* base;
int* top;
int stacksize;
} SqStack;
void CreateStack(SqStack* S) {
S->base = (int*)malloc(STACK_INIT_SIZE * sizeof(int));
if (!S->base) {
cout << "存储空间分配失败!" << endl;
exit(-1);
}
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
}
void DestroySqStack(SqStack* S) {
free(S->base);
S->base = S->top = NULL;
S->stacksize = 0;
}
void DisplaySqStack(SqStack* S) {
int* p;
if (S->top == S->base) {
cout << "栈空!" << endl;
exit(-1);
}
p = S->base;
while (p < S->top - 1)
cout << *p++ << "->";
cout << *p++;
}
void Push(SqStack* S, int data) {
if (S->top - S->base == S->stacksize) {
int* newbase = (int*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(int));
if (!newbase) {
cout << "存储空间分配失败!" << endl;
exit(-1);
}
S->base = newbase;
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = data;
}
void Pop(SqStack* S) {
if (S->top == S->base) {
cout << "栈空!" << endl;
exit(-1);
}
S->top--;
}
int GetTop(SqStack* S) {
if (S->top == S->base) {
cout << "栈空!" << endl;
exit(-1);
}
return *(S->top - 1);
}
int StackLength(SqStack* S) {
return S->top - S->base;
}
int visited[VEX_MAXNUM];
typedef struct EdgeNode {
int vex_index;
struct EdgeNode* next;
} EdgeNode;
typedef struct VexNode {
int data;
EdgeNode* edge;
} VexNode, AdjList[VEX_MAXNUM];
typedef struct Graph {
AdjList list;
int vexnum, edgenum;
} Graph;
int LocateIndex(Graph* G, int v) {
int i = 0, j = G->vexnum - 1, mid;
while (i <= j) {
mid = (i + j) / 2;
if (G->list[mid].data == v)
break;
else if (v > G->list[mid].data)
i = mid + 1;
else
j = mid - 1;
}
if (i > j) {
cout << "顶点不存在!" << endl;
exit(-1);
}
return mid;
}
void CreateGraph(Graph* G) {
cout << "请输入图的顶点数和边数:" << endl;
cin >> G->vexnum >> G->edgenum;
cout << "请输入顶点:" << endl;
for (int i = 0; i < G->vexnum; i++) {
cin >> G->list[i].data;
G->list[i].edge = NULL;
}
cout << "请输入边:" << endl;
for (int k = 0; k < G->edgenum; k++) {
int v1, v2, i, j;
EdgeNode* p, * q;
cin >> v1 >> v2;
i = LocateIndex(G, v1);
j = LocateIndex(G, v2);
p = (EdgeNode*)malloc(sizeof(EdgeNode));
p->vex_index = j;
p->next = NULL;
q = G->list[i].edge;
if (!q)
G->list[i].edge = p;
else {
while (q->next)
q = q->next;
q->next = p;
}
p = (EdgeNode*)malloc(sizeof(EdgeNode));
p->vex_index = i;
p->next = NULL;
q = G->list[j].edge;
if (!q)
G->list[j].edge = p;
else {
while (q->next)
q = q->next;
q->next = p;
}
}
}
void DestroyGraph(Graph* G) {
VexNode* p;
EdgeNode* q;
for (int i = 0; i < G->vexnum; i++) {
p = &G->list[i];
while (p->edge) {
q = p->edge;
p->edge = q->next;
free(q);
}
}
}
void DFSALLPath(Graph* G, int index1, int index2, SqStack* S) {
EdgeNode* p;
visited[index1] = 1;
Push(S, index1);
if (index1 == index2) {
DisplaySqStack(S);
cout << endl;
Pop(S);
visited[index1] = 0;
return;
}
p = G->list[index1].edge;
while (p) {
if (!visited[p->vex_index])
DFSALLPath(G, p->vex_index, index2, S);
p = p->next;
}
Pop(S);
visited[index1] = 0;
}
void PrintAllPath(Graph* G, int index1, int index2) {
SqStack S;
CreateStack(&S);
for (int i = 0; i < G->vexnum; i++)
visited[i] = 0;
DFSALLPath(G, index1, index2, &S);
}
int main() {
Graph G;
int start, end;
CreateGraph(&G);
cout << "请输入起点:" << endl;
cin >> start;
cout << "请输入终点:" << endl;
cin >> end;
cout << "两顶点间的所有路径:" << endl;
PrintAllPath(&G, LocateIndex(&G, start), LocateIndex(&G, end));
DestroyGraph(&G);
return 0;
}

代码解释

  • 邻接表的实现

    • 邻接表通过一个数组存储每个顶点的相邻顶点信息。每个顶点对应一个数据结构,包含一个边指针和一个顶点索引。
  • 图的创建

    • 使用CreateGraph函数输入顶点和边,顶点通过数组存储,边通过邻接表连接顶点。
  • 深度优先搜索(DFS)

    • DFSALLPath函数从起点开始,逐层遍历所有可能的路径,记录访问过的顶点,避免重复路径。
  • 路径输出

    • PrintAllPath函数使用一个栈保存路径信息,逐层展示所有从起点到终点的路径。
  • 代码执行流程

    • 首先创建图的数据结构,输入顶点和边信息。
    • 读取起点和终点,调用PrintAllPath函数输出所有路径。
    • 最后销毁图的数据结构,释放内存。
  • 通过上述代码,可以实现对任意图的邻接表存储,并输出两点间的所有路径。

    转载地址:http://wieq.baihongyu.com/

    你可能感兴趣的文章
    MySQL 快速创建千万级测试数据
    查看>>
    mysql 快速自增假数据, 新增假数据,mysql自增假数据
    查看>>
    MySql 手动执行主从备份
    查看>>
    Mysql 批量修改四种方式效率对比(一)
    查看>>
    mysql 批量插入
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>
    Mysql 拼接多个字段作为查询条件查询方法
    查看>>
    mysql 排序id_mysql如何按特定id排序
    查看>>
    Mysql 提示:Communication link failure
    查看>>
    mysql 插入是否成功_PDO mysql:如何知道插入是否成功
    查看>>
    Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
    查看>>
    mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
    查看>>
    mysql 数据库备份及ibdata1的瘦身
    查看>>
    MySQL 数据库备份种类以及常用备份工具汇总
    查看>>
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>
    MySQL 数据库设计总结
    查看>>
    Mysql 数据库重置ID排序
    查看>>