邻接表法存储

邻接表发存储需要时无权无向图。用数组+链表的方式完成
数组用来记录地点,链表来记录每一个地点对应的相邻地点
1.构造一个数据结构来存放数组的序号以及指针用来指向链表
2.创造结点,构建链表
3.采用无表头链表表头插入法,来插入链表(此时链表的部分已经完成,可以顺利使1,3完成连接)
4.构造数组,用来存放数据,以及每一个数据都带有的指针
5.构造图,结构体里含有边数与顶点数,以及结构体数组(也就是第四步)
6.创建图,因为我们要插入插入到链表(例如B插入A),所以要先找到A对应的数组位置(第七步),找到位置后完成插入(第三步)
7.在图里搜索对应的位置
8.主函数

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 10
typedef char VertexType[4];
//存放邻接顶点的链表
typedef struct ArcNode
{int vexIndex;//顶点在顶点数组中的序号struct ArcNode* next;//链表必备
}NODE,*LPNODE;
//要插入链表,要先创造链表的结点
LPNODE createNode(int vexIndex)
{LPNODE newNode = (LPNODE)malloc(sizeof(NODE));newNode->vexIndex=vexIndex;newNode->next =NULL;return newNode;
}
//接下来是连接链表,无表头链表表头法插入
//LPNODE *headNode 二级指针
void insertNodeByHead(LPNODE *headNode, int vexIndex)
{LPNODE newNode = createNode(vexIndex);newNode->next = *headNode;*headNode = newNode;
}
//图结构: 数组+链表
//描述顶点信息
typedef struct VNode
{VertexType data;//存放数据LPNODE firstNode;//每一个数据都带一个指针
}VNODE,ARRAY[MAX],*LPVNODE;typedef struct GRAPH
{int arcnum;//边数int vexnum;//顶点数ARRAY vextex;//结构体数组
}GRAPH,*LPGRAPH;
int serchPos(LPGRAPH G,VertexType x)
{int i;for(i=0;i<G->vexnum;i++){if(strcmp(G->vextex[i].data,x)==0)return i;}return -1;
}
LPGRAPH createGraph()
{LPGRAPH G =(LPGRAPH)malloc(sizeof(GRAPH));printf("请输入边数的顶点数:");scanf("%d%d",&G->arcnum,&G->vexnum);printf("请输入%d个顶点:\n",G->vexnum);int i;for(i=0;i<G->vexnum;i++){scanf("%s",G->vextex[i].data);G->vextex[i].firstNode=NULL;}VertexType v1,v2;int posV1;int posV2;printf("请输入边的信息:\n");for(i=0;i<G->arcnum;i++){scanf("%s%s",v1,v2);posV1=serchPos(G,v1);posV2=serchPos(G,v2);//找到下标是为了插入链表//因为是无向所以V1和V2互相插入insertNodeByHead(&G->vextex[posV1].firstNode,posV2);insertNodeByHead(&G->vextex[posV2].firstNode,posV1);}return G;
}
void printfGraph(LPGRAPH G)
{int i;for(i=0;i<G->vexnum;i++){printf("%s-->",G->vextex[i].data);LPNODE pMove=G->vextex[i].firstNode;while(pMove){printf("%s-->",G->vextex[pMove->vexIndex].data);pMove=pMove->next;}printf("\n");}
}
int main()
{LPGRAPH G= createGraph();printfGraph(G);system("pause");return 0;
}

结果如下:
请输入边数的顶点数:5 4
请输入4个顶点:
A B C D
请输入边的信息:
A B
B C
A C
B D
D C
A–>C–>B–>
B–>D–>C–>A–>
C–>D–>A–>B–>
D–>C–>B–>
请按任意键继续. . .

广度优先遍历BFS

1.选定一个入口
2.访问所有当前顶点的所有邻接顶点
3.出队,打印链表,找当前顶点的邻接顶点
4.标记已经遍历的顶点,避免重复打印
代码与邻接表发存储图一致,就打印的函数不一样
打印函数代码

void visitVextex(VertexType x)
{printf("%s-->",x);
}
void BFSTravers(LPGRAPH G,int inPos)
{int visited[MAX]={0};//访问标记int queue[MAX];int front =-1;int tail=-1;visitVextex(G->vextex[inPos].data);visited[inPos]=1;//访问后,标记为1;queue[++tail]=inPos;//访问的下标入队LPNODE pMove = NULL;while(front <tail){inPos=queue[++front];//出队pMove =G->vextex[inPos].firstNode;while(pMove){if(visited[pMove->vexIndex]==0){visitVextex(G->vextex[pMove->vexIndex].data);visited[pMove->vexIndex]=1;//把访问的元素入队queue[++tail]=pMove->vexIndex;}pMove=pMove->next;//被打印不做处理}}
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 10
typedef char VertexType[4];
//存放邻接顶点的链表
typedef struct ArcNode
{int vexIndex;//顶点在顶点数组中的序号struct ArcNode* next;//链表必备
}NODE,*LPNODE;
//要插入链表,要先创造链表的结点
LPNODE createNode(int vexIndex)
{LPNODE newNode = (LPNODE)malloc(sizeof(NODE));newNode->vexIndex=vexIndex;newNode->next =NULL;return newNode;
}
//接下来是连接链表,无表头链表表头法插入
//LPNODE *headNode 二级指针
void insertNodeByHead(LPNODE *headNode, int vexIndex)
{LPNODE newNode = createNode(vexIndex);newNode->next = *headNode;*headNode = newNode;
}
//图结构: 数组+链表
//描述顶点信息
typedef struct VNode
{VertexType data;//存放数据LPNODE firstNode;//每一个数据都带一个指针
}VNODE,ARRAY[MAX],*LPVNODE;typedef struct GRAPH
{int arcnum;//边数int vexnum;//顶点数ARRAY vextex;//结构体数组
}GRAPH,*LPGRAPH;
int serchPos(LPGRAPH G,VertexType x)
{int i;for(i=0;i<G->vexnum;i++){if(strcmp(G->vextex[i].data,x)==0)return i;}return -1;
}
LPGRAPH createGraph()
{LPGRAPH G =(LPGRAPH)malloc(sizeof(GRAPH));printf("请输入边数的顶点数:");scanf("%d%d",&G->arcnum,&G->vexnum);printf("请输入%d个顶点:\n",G->vexnum);int i;for(i=0;i<G->vexnum;i++){scanf("%s",G->vextex[i].data);G->vextex[i].firstNode=NULL;}VertexType v1,v2;int posV1;int posV2;printf("请输入边的信息:\n");for(i=0;i<G->arcnum;i++){scanf("%s%s",v1,v2);posV1=serchPos(G,v1);posV2=serchPos(G,v2);//找到下标是为了插入链表//因为是无向所以V1和V2互相插入insertNodeByHead(&G->vextex[posV1].firstNode,posV2);insertNodeByHead(&G->vextex[posV2].firstNode,posV1);}return G;
}
void visitVextex(VertexType x)
{printf("%s-->",x);
}
void BFSTravers(LPGRAPH G,int inPos)
{int visited[MAX]={0};//访问标记int queue[MAX];int front =-1;int tail=-1;visitVextex(G->vextex[inPos].data);visited[inPos]=1;//访问后,标记为1;queue[++tail]=inPos;//访问的下标入队LPNODE pMove = NULL;while(front <tail){inPos=queue[++front];//出队pMove =G->vextex[inPos].firstNode;while(pMove){if(visited[pMove->vexIndex]==0){visitVextex(G->vextex[pMove->vexIndex].data);visited[pMove->vexIndex]=1;//把访问的元素入队queue[++tail]=pMove->vexIndex;}pMove=pMove->next;//被打印不做处理}}
}
int main()
{LPGRAPH G= createGraph();BFSTravers(G,0);printf("\n");system("pause");return 0;
}

结果
请输入边数的顶点数:4 5
请输入5个顶点:
A B C D E
请输入边的信息:
A B
A C
B D
C E
A–>C–>B–>E–>D–>
请按任意键继续. . .

深度优先遍历(DFS)—3.14补充

深度优先相当于走迷宫,先一路走到底,发现走不了了再退回去尝试其他的路径
1.访问顶点
2.将访问过的顶点标记为1,并将之地址记录到数组栈里
3.访问其邻接顶点的顶点,也就是跳转
4.访问过的跳过访问下一个,没访问过,标记,并存入栈,继续跳转
5.为空时说明已经访问完了,这时候出栈,出完栈后,指针指向栈顶的地址再依次重复,直到栈顶为空,或指针为空
核心代码

void visitVextex(VertexType x)
{printf("%s-->",x);
}
void DFSTravers(LPGRAPH G ,int inPos)
{//数组栈,用来存放指针,用来跳转LPNODE stack[MAX];int top=-1;//访问标记int visited[MAX]={0};//选定入口visitVextex(G->vextex[inPos].data);visited[inPos]=1;//打印入口链表,打印一个结点跳转LPNODE pMove=G->vextex[inPos].firstNode;while(top>-1||pMove!=NULL){while(pMove){if(visited[pMove->vexIndex]==1){//被访问过直接跳过pMove=pMove->next;}else//没被访问过,则访问一下,并标记,入栈{visitVextex(G->vextex[pMove->vexIndex].data);visited[pMove->vexIndex]=1;stack[++top]=pMove;//跳到当前访问过序号的那个链表中去pMove= G->vextex[pMove->vexIndex].firstNode;}}//无路可走时出栈if(top>-1){pMove=stack[top--];pMove=pMove->next;}}}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 10
typedef char VertexType[4];
//存放邻接顶点的链表
typedef struct ArcNode
{int vexIndex;//顶点在顶点数组中的序号struct ArcNode* next;//链表必备
}NODE,*LPNODE;
//要插入链表,要先创造链表的结点
LPNODE createNode(int vexIndex)
{LPNODE newNode = (LPNODE)malloc(sizeof(NODE));newNode->vexIndex=vexIndex;newNode->next =NULL;return newNode;
}
//接下来是连接链表,无表头链表表头法插入
//LPNODE *headNode 二级指针
void insertNodeByHead(LPNODE *headNode, int vexIndex)
{LPNODE newNode = createNode(vexIndex);newNode->next = *headNode;*headNode = newNode;
}
//图结构: 数组+链表
//描述顶点信息
typedef struct VNode
{VertexType data;//存放数据LPNODE firstNode;//每一个数据都带一个指针
}VNODE,ARRAY[MAX],*LPVNODE;typedef struct GRAPH
{int arcnum;//边数int vexnum;//顶点数ARRAY vextex;//结构体数组
}GRAPH,*LPGRAPH;
int serchPos(LPGRAPH G,VertexType x)
{int i;for(i=0;i<G->vexnum;i++){if(strcmp(G->vextex[i].data,x)==0)return i;}return -1;
}LPGRAPH createGraph()
{LPGRAPH G =(LPGRAPH)malloc(sizeof(GRAPH));printf("请输入边数和顶点数:");scanf("%d%d",&G->arcnum,&G->vexnum);printf("请输入%d个顶点:\n",G->vexnum);int i;for(i=0;i<G->vexnum;i++){scanf("%s",G->vextex[i].data);G->vextex[i].firstNode=NULL;}VertexType v1,v2;int posV1;int posV2;printf("请输入边的信息:\n");for(i=0;i<G->arcnum;i++){scanf("%s%s",v1,v2);posV1=serchPos(G,v1);posV2=serchPos(G,v2);//找到下标是为了插入链表//因为是无向所以V1和V2互相插入insertNodeByHead(&G->vextex[posV1].firstNode,posV2);insertNodeByHead(&G->vextex[posV2].firstNode,posV1);}return G;
}
void visitVextex(VertexType x)
{printf("%s-->",x);
}
void DFSTravers(LPGRAPH G ,int inPos)
{//数组栈,用来存放指针,用来跳转LPNODE stack[MAX];int top=-1;//访问标记int visited[MAX]={0};//选定入口visitVextex(G->vextex[inPos].data);visited[inPos]=1;//打印入口链表,打印一个结点跳转LPNODE pMove=G->vextex[inPos].firstNode;while(top>-1||pMove!=NULL){while(pMove){if(visited[pMove->vexIndex]==1){//被访问过直接跳过pMove=pMove->next;}else//没被访问过,则访问一下,并标记,入栈{visitVextex(G->vextex[pMove->vexIndex].data);visited[pMove->vexIndex]=1;stack[++top]=pMove;//跳到当前访问过序号的那个链表中去pMove= G->vextex[pMove->vexIndex].firstNode;}}//无路可走时出栈if(top>-1){pMove=stack[top--];pMove=pMove->next;}}}
int main()
{LPGRAPH G= createGraph();DFSTravers(G,0);system("pause");return 0;
}

结果:

请输入边数和顶点数:4 5
请输入5个顶点:
A B C D E
请输入边的信息:
A B
A C
B D
C E
A–>C–>E–>B–>D–>请按任意键继续. . .
———————————————————
10000小时计划
48.5h

一一计划(Day 14)邻接表法存储图,BFS广度优先遍历,DFS深度优先遍历相关推荐

  1. 邻接表形式存储图并且按广度优先搜索遍历的C语言实现

    用邻接表形式存储图并且按广度优先搜索打印遍历结果 #include<stdio.h> #define MAX_VERTEX_NUM 20//最多顶点个数 #define ERROR -1t ...

  2. 数据结构之图的存储结构:邻接表法

    图的存储结构:邻接表法 产生条件: 邻接表法的定义: 邻接表法的特点: 邻接表法的代码定义: 邻接表法与邻接矩阵法的对比: 产生条件: 当用邻接矩阵存储时:空间复杂度为O(|v|^2),太大 邻接表法 ...

  3. 图的存储结构——邻接表法

    图的存储结构--邻接表法 一.邻接表 ​ 由顶点表和边表构成,顶点表由顶点域(data)和指向第一条邻接边的指针(firstarc)构成,边表(邻接表)结点由邻接点域(adjvex)和指向下一条邻接边 ...

  4. 图——图的存储结构(邻接矩阵和邻接表法)

    图的五种存储结构: 1.图的邻接矩阵表示法 图是由顶点和边或弧两部分组成.图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组表示图,一个一维数组存储图中的顶点信息,一个二维数组(邻接 ...

  5. 图的存储——邻接表法

    文章目录 一.邻接表法 二.复杂度分析(G(V,E)) 1.无向图 2.有向图 总结(和邻接矩阵的对比) 一.邻接表法 使用一个顶点表存储顶点信息,每个顶点之后连接该顶点的相连边的信息(链表). 结构 ...

  6. dijkstra迪杰斯特拉算法(邻接表法)

    算法简易过程: 迪杰斯特拉算法(朴素) O(n^2) G={V,E} V:点集合 E:边集合 初始化时 令 S={某源点ear}, T=V-S= {其余顶点},T中顶点对应的距离(ear, Vi)值若 ...

  7. 无向图有向图的邻接表法建立

    目录 无向图的邻接表法建立 有向图的邻接表法 无向图的邻接表法建立 要求建立一个无向图,采用邻接表做为存储结构. 例如: 输入信息为:第一行给出图的顶点数n和边数e.第二行给出n个字符,表示n个顶点的 ...

  8. 邻接表存储图的广度优先遍历

    试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ); 其中LGraph是邻接表存储 ...

  9. 实现图的邻接矩阵和邻接表的存储

    十五,实现图的邻接矩阵和邻接表的存储 #include<stdio.h> #include<stdlib.h> #define max 100 #define INF 3276 ...

最新文章

  1. 【linux】route使用小结
  2. 为什么要学数学?因为这是一场战略性的投资
  3. prototype原型模式
  4. tensorflow 数据格式
  5. SLES修改本地FTP安装源
  6. Linux 命令之 which -- 查找并显示给定命令的绝对路径(查找命令的位置/查询命令的位置/搜索命令的位置/查看命令的位置)
  7. linux快速删除60万文件,Linux下快速删除大量文件
  8. 为什么我建议你这样实现MySQL分页
  9. [乱七八糟]分享今晚瞎逛来的网络东东
  10. 毕业论文 一级标题段前段后问题
  11. C++项目设计与总结
  12. 【转】win10更改C盘中用户文件夹名
  13. 时尚圈美女撰文主攻方向
  14. 一位老中医的养生忠告
  15. UVA10815 安迪的第一个字典 Andy‘s First Dictionary
  16. Google Adsense西联汇款邮政储蓄收款流程
  17. python如何撤销上一步_python代码运行到某一步能返回到前面某一步吗?
  18. 嵌入式系统开发笔记91:认识ARM微控制器架构
  19. STM32串口中 USART_GetITStatus 与 USART_GetFlagStatus的区别
  20. 实战nodejs写网络爬虫

热门文章

  1. MT5交易软件使用技巧
  2. Linux找回mysql的root密码
  3. 虹科网络流量监控软件解决方案(二)-- 网络探针nProbe
  4. Intellij IDEA 安装和配置热部署插件JRebel进行项目的热部署
  5. kafka 自定义Interceptor(通过拦截器对消息进行定制化处理)
  6. python通过异步爬取小说
  7. 洛谷10月月赛Round.1| P3400 仓鼠窝[单调栈]
  8. 第4章-5 求e的近似值 (15分)python
  9. 万能通用的各大网站(全民简历、简历本等) 简历模板 -- 免费下载方法
  10. 存在重复元素-python对不起算法大人,我又来水了