赞
踩
目录
算法核心:
现有一组无向图,要求用DFS和BFS遍历图,依次输出相关值。
采用读取text文件,第一阶段依次读取文件中的顶点表数量和边表的数量,第二阶段读取各个顶点的名称,第三阶段读取各边表的两个下标位置。(注意:若是构建有向图的,可以在赋予边表时候只赋给一边,本案例是按照无向图双边赋值)。
申明变量(链表、节点、队列)
- #include<stdio.h>
- #include<stdlib.h>
- //#include<malloc.h>
- #define _CRT_SECURE_NO_WARNINGS
- #define MaxVertices 100
- #define MaxVertNum 100
- #define MAX 10
-
- typedef int VertextType;//顶点类型应由用户定义
- //typedef int EdgeType;//边上的权值类型应由用户定义
- /*边表结点*/
- typedef struct EdgeNode {//边表结点 边表
- int adjvex;//邻接点域,存储该顶点对应的下标
- //EdgeType weight;//用于存储权值,对于非网图可以不需要
- struct EdgeNode* next;//链域,指向下一个邻接点
- }EdgeNode;
-
- typedef struct VertextNode {//顶点表结点 顶点表
- VertextType data;//顶点域,存储顶点信息
- EdgeNode* firstedge;//边表头指针
- }VertexNode;
-
- typedef VertexNode AdjList[MaxVertices];//顶点表数组
-
- typedef struct {
- //VertexNode adjList[MaxVertices];
- AdjList adjList;//存放所有顶点表的数组-> VertexNode adjList[MaxVertices]
- int numVertexes, numEdges;//图中当前顶点数和边数
- }GraphAdjList;
- typedef GraphAdjList* GraphAdj;
-
-
- typedef struct LoopQueue{ //定义循环队列结构体
- int data[MAX];
- int front;
- int rear; //注意每次队尾标记指向最后一个元素的下一个位置
- }Queue, *LQueue;
-
- void InitQueue(LQueue &Q){ //初始化队列
- Q->front = Q->rear = 0;
- }
-
- bool QueueisFull(LQueue &Q){ //判断队列是否满了
- if((Q->rear + 1) % MAX == Q->front){
- return true; //已满
- }
- else{
- return false;
- }
- }
-
- bool QueueisEmpty(LQueue &Q){//判断队列是否为空
- if(Q->front == Q->rear){
- return true;
- }
- return false;
- }
-
-
- void EnQueue(LQueue &Q, int i){ //入队列
- if(!QueueisFull(Q)){
- Q->data[Q->rear] = i;
- Q->rear = (Q->rear + 1) % MAX; //队尾指针后移
- }
- }
-
- void DeQueue(LQueue &Q, int *k){ //出队列
- if(!QueueisEmpty(Q)){
- *k = Q->data[Q->front];
- Q->front = (Q->front + 1) % MAX;
- }
- }

- int InitGraph(GraphAdj G) {
-
- int i, j;
- EdgeNode* s;//新的边结点
- FILE* fp = NULL;
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList2.txt", "rb");
- if (fp == NULL) {
- printf("ERROR");
- return -1;
- }
- fscanf(fp, "%d %d", &G->numVertexes, &G->numEdges);//顶点数,边数
-
- /*******************创建顶点表**************************/
- for (i = 0; i < G->numVertexes; i++) {
- fscanf(fp, "%d", &G->adjList[i].data);
- G->adjList[i].firstedge = NULL;//注意将边表置空
- }
-
- /******************创建边表****************************/
- for (int k = 0; k < G->numEdges; k++) {
- fscanf(fp, "%d %d", &i, &j);//"输入边(Vi,Vj)上的顶点序号
-
- //对于直接相连的进行编入(即对输入“0 1”时,在0对应的边表中编入1)
- s = (EdgeNode*)malloc(sizeof(EdgeNode));
- s->adjvex = j;//边表赋值
- s->next = G->adjList[i].firstedge;
- G->adjList[i].firstedge = s;
-
- //对于间接相连的进行编入(即对输入“0 1”时,在1对应的边表中编入0)
- s = (EdgeNode*)malloc(sizeof(EdgeNode));
- s->adjvex = i;
- s->next = G->adjList[j].firstedge;
- G->adjList[j].firstedge = s;
- }
-
- fclose(fp);
- }
-
-
-
- void DisplayGraph(GraphAdjList* G) {
- int i;
- FILE *fp;
- /**文档输出 ***/
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList_result.txt", "w");
- if (fp == NULL) {
- printf("ERROR");
- // return -1;
- }
- fprintf(fp, "Enter contents to store in file : \n");
- EdgeNode* p;
- for (int i = 0; i < G->numVertexes; i++) {
- p = G->adjList[i].firstedge;
- printf("%d->", i);
- fprintf(fp, "%d->", i);
- while (1) {
- if (p == NULL) {
- printf("^");
- fprintf(fp, "^");
- break;
- }
- printf("%d->", p->adjvex);//输出边表的下标,但这里可以表示原有的 数
- fprintf(fp, "%d->", p->adjvex);
- p = p->next;
- }
- printf("\n");
- fprintf(fp, "\n");
- }
-
- fclose(fp);//???
- }

- int main() {
- int index, flage = 1;
- GraphAdjList* G = (GraphAdjList*)malloc(sizeof(GraphAdjList));
- InitGraph(G);
- printf("现有无向图的链表存储:\n");
- DisplayGraph(G);
-
- while (flage) {
- printf("现有无向图的DFS(按1):\n");
- printf("现有无向图的BFS(按2):\n");
- printf("退出遍历(按3):\n");
- //DFSTraverse(G);
- scanf("%d", &index);
- switch (index) {
- case 1:
- DFS(G, 0);
- break;
- case 2:
- BFS(G,0);
- break;
- case 3:
- flage = 0;
- break;
- }
- }
- return 0;
- }

DFS部分。运用栈。将head后面依次放入栈中,并选取栈头的visit为1置为新的head,遍历其后面的依次放入栈中,直到栈为空结束。
- void DFS(GraphAdjList* G, int v0) { //图,下标位置
- int stack[MaxVertNum];
- EdgeNode* p;
- int visited[MaxVertNum] = { 0 }, top = -1, v;
- printf("此图的DFS遍历:\n");
- //p = G->adjList[v0].firstedge;
- stack[++top] = v0;//top=0,存储第一个数v0(下标)
-
- FILE *fp; /**文档输出 ***/
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList_result_DFS.txt", "w");
- if (fp == NULL) {
- printf("ERROR");
- // return -1;
- }
- fprintf(fp, "此图的DFS遍历:\n");
-
- while (top != -1)//判断栈有无有空
- {
- v = stack[top--];//出栈 v(数值data/下标)
- if (!visited[v]) {//v 未被访问
- printf("%d ", G->adjList[v].data);
- fprintf(fp, "%d ", G->adjList[v].data);
- visited[v] = 1;
- }
- p = G->adjList[v].firstedge;//边结点指针
- while (p) {
- if (!visited[p->adjvex]) {//p边结点的下标有无访问到
- stack[++top] = p->adjvex;
- }
- p = p->next;
- }
- }
- fclose(fp);
- printf("\n");
- }

BFS部分。运用队列。将head后面依次放入队列中,并选取队头的取出,其visit为1置为新的head,遍历其后面的依次放入队列中,直到队列为空结束。
- void BFS(GraphAdjList* G,int i){
- int visited[MaxVertNum] = { 0 };
- //int i = 0;
- Queue *Q =(LQueue)malloc(sizeof(Queue));
- for(int i = 0; i < G->numVertexes; i++){
- visited[i] = 0;
- }
-
- FILE *fp; /**文档输出 ***/
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList_result_BFS.txt", "w");
- if (fp == NULL) {
- printf("ERROR");
- // return -1;
- }
- fprintf(fp, "此图的BFS遍历:\n");
-
- InitQueue(Q); //初始化队列
-
- visited[i] = 1;//从0下标开始
- printf("%d ", G->adjList[i].data);
- fprintf(fp,"%d ", G->adjList[i].data);
-
- EnQueue(Q, i);//入队?
-
- while(!QueueisEmpty(Q)){//根据队列遍历全部顶点坐标
- DeQueue(Q, &i); //这里不断的修改i的值,队头元素出队,改变i值?
- EdgeNode *e = G->adjList[i].firstedge; //i顶点的邻接链表的第一个结点
- while(e){//e存在时,将e的所有邻接点加入队列,也就是遍历i的所有邻接点
- if(!visited[e->adjvex]){ // adjvex是e所表示的结点下标
- visited[e->adjvex] = 1;
- printf("%d ", G->adjList[e->adjvex].data);//输出顶点下标的数值
- fprintf(fp,"%d ", G->adjList[e->adjvex].data);//输出顶点下标的数值
- EnQueue(Q, e->adjvex); //将该结点入队
- }
- e = e->next; //遍历i的下一个邻接点
- }
- }
-
- printf("\n");
- fclose(fp);
- }

- #include<stdio.h>
- #include<stdlib.h>
- //#include<malloc.h>
- #define _CRT_SECURE_NO_WARNINGS
- #define MaxVertices 100
- #define MaxVertNum 100
- #define MAX 10
-
- typedef int VertextType;//顶点类型应由用户定义
- //typedef int EdgeType;//边上的权值类型应由用户定义
- /*边表结点*/
- typedef struct EdgeNode {//边表结点 边表
- int adjvex;//邻接点域,存储该顶点对应的下标
- //EdgeType weight;//用于存储权值,对于非网图可以不需要
- struct EdgeNode* next;//链域,指向下一个邻接点
- }EdgeNode;
-
- typedef struct VertextNode {//顶点表结点 顶点表
- VertextType data;//顶点域,存储顶点信息
- EdgeNode* firstedge;//边表头指针
- }VertexNode;
-
- typedef VertexNode AdjList[MaxVertices];//顶点表数组
-
- typedef struct {
- //VertexNode adjList[MaxVertices];
- AdjList adjList;//存放所有顶点表的数组-> VertexNode adjList[MaxVertices]
- int numVertexes, numEdges;//图中当前顶点数和边数
- }GraphAdjList;
- typedef GraphAdjList* GraphAdj;
-
- int InitGraph(GraphAdj G) {
-
- int i, j;
- EdgeNode* s;//新的边结点
- FILE* fp = NULL;
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList2.txt", "rb");
- if (fp == NULL) {
- printf("ERROR");
- return -1;
- }
- fscanf(fp, "%d %d", &G->numVertexes, &G->numEdges);//顶点数,边数
-
- /*******************创建顶点表**************************/
- for (i = 0; i < G->numVertexes; i++) {
- fscanf(fp, "%d", &G->adjList[i].data);
- G->adjList[i].firstedge = NULL;//注意将边表置空
- }
-
- /******************创建边表****************************/
- for (int k = 0; k < G->numEdges; k++) {
- fscanf(fp, "%d %d", &i, &j);//"输入边(Vi,Vj)上的顶点序号
-
- //对于直接相连的进行编入(即对输入“0 1”时,在0对应的边表中编入1)
- s = (EdgeNode*)malloc(sizeof(EdgeNode));
- s->adjvex = j;//边表赋值
- s->next = G->adjList[i].firstedge;
- G->adjList[i].firstedge = s;
-
- //对于间接相连的进行编入(即对输入“0 1”时,在1对应的边表中编入0)
- s = (EdgeNode*)malloc(sizeof(EdgeNode));
- s->adjvex = i;
- s->next = G->adjList[j].firstedge;
- G->adjList[j].firstedge = s;
- }
-
- fclose(fp);
- }
-
-
-
- void DisplayGraph(GraphAdjList* G) {
- int i;
- FILE *fp;
- /**文档输出 ***/
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList_result.txt", "w");
- if (fp == NULL) {
- printf("ERROR");
- // return -1;
- }
- fprintf(fp, "Enter contents to store in file : \n");
- EdgeNode* p;
- for (int i = 0; i < G->numVertexes; i++) {
- p = G->adjList[i].firstedge;
- printf("%d->", i);
- fprintf(fp, "%d->", i);
- while (1) {
- if (p == NULL) {
- printf("^");
- fprintf(fp, "^");
- break;
- }
- printf("%d->", p->adjvex);//输出边表的下标,但这里可以表示原有的 数
- fprintf(fp, "%d->", p->adjvex);
- p = p->next;
- }
- printf("\n");
- fprintf(fp, "\n");
- }
-
- fclose(fp);//???
- }
-
- void DFS(GraphAdjList* G, int v0); //图,下标位置
- void BFS(GraphAdjList* G,int v0);
-
-
- int main() {
- int index, flage = 1;
- GraphAdjList* G = (GraphAdjList*)malloc(sizeof(GraphAdjList));
- InitGraph(G);
- printf("现有无向图的链表存储:\n");
- DisplayGraph(G);
-
- while (flage) {
- printf("现有无向图的DFS(按1):\n");
- printf("现有无向图的BFS(按2):\n");
- printf("退出遍历(按3):\n");
- //DFSTraverse(G);
- scanf("%d", &index);
- switch (index) {
- case 1:
- DFS(G, 0);
- break;
- case 2:
- BFS(G,0);
- break;
- case 3:
- flage = 0;
- break;
- }
-
- }
-
- return 0;
- }
-
- /********************DFS*************************************/
- void DFS(GraphAdjList* G, int v0) { //图,下标位置
- int stack[MaxVertNum];
- EdgeNode* p;
- int visited[MaxVertNum] = { 0 }, top = -1, v;
- printf("此图的DFS遍历:\n");
- //p = G->adjList[v0].firstedge;
- stack[++top] = v0;//top=0,存储第一个数v0(下标)
-
- FILE *fp; /**文档输出 ***/
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList_result_DFS.txt", "w");
- if (fp == NULL) {
- printf("ERROR");
- // return -1;
- }
- fprintf(fp, "此图的DFS遍历:\n");
-
- while (top != -1)//判断栈有无有空
- {
- v = stack[top--];//出栈 v(数值data/下标)
- if (!visited[v]) {//v 未被访问
- printf("%d ", G->adjList[v].data);
- fprintf(fp, "%d ", G->adjList[v].data);
- visited[v] = 1;
- }
- p = G->adjList[v].firstedge;//边结点指针
- while (p) {
- if (!visited[p->adjvex]) {//p边结点的下标有无访问到
- stack[++top] = p->adjvex;
- }
- p = p->next;
- }
- }
- fclose(fp);
- printf("\n");
- }
- /********************BFS*************************************/
-
-
- typedef struct LoopQueue{ //定义循环队列结构体
- int data[MAX];
- int front;
- int rear; //注意每次队尾标记指向最后一个元素的下一个位置
- }Queue, *LQueue;
-
- void InitQueue(LQueue &Q){ //初始化队列
- Q->front = Q->rear = 0;
- }
-
- bool QueueisFull(LQueue &Q){ //判断队列是否满了
- if((Q->rear + 1) % MAX == Q->front){
- return true; //已满
- }
- else{
- return false;
- }
- }
-
- bool QueueisEmpty(LQueue &Q){//判断队列是否为空
- if(Q->front == Q->rear){
- return true;
- }
- return false;
- }
-
-
- void EnQueue(LQueue &Q, int i){ //入队列
- if(!QueueisFull(Q)){
- Q->data[Q->rear] = i;
- Q->rear = (Q->rear + 1) % MAX; //队尾指针后移
- }
- }
-
- void DeQueue(LQueue &Q, int *k){ //出队列
- if(!QueueisEmpty(Q)){
- *k = Q->data[Q->front];
- Q->front = (Q->front + 1) % MAX;
- }
- }
-
- void BFS(GraphAdjList* G,int i){
- int visited[MaxVertNum] = { 0 };
- //int i = 0;
- Queue *Q =(LQueue)malloc(sizeof(Queue));
- for(int i = 0; i < G->numVertexes; i++){
- visited[i] = 0;
- }
-
- FILE *fp; /**文档输出 ***/
- fp = fopen("D://Project//shuJuJieGou//DFS//GraphAdjList_result_BFS.txt", "w");
- if (fp == NULL) {
- printf("ERROR");
- // return -1;
- }
- fprintf(fp, "此图的BFS遍历:\n");
-
- InitQueue(Q); //初始化队列
-
- visited[i] = 1;//从0下标开始
- printf("%d ", G->adjList[i].data);
- fprintf(fp,"%d ", G->adjList[i].data);
-
- EnQueue(Q, i);//入队?
-
- while(!QueueisEmpty(Q)){//根据队列遍历全部顶点坐标
- DeQueue(Q, &i); //这里不断的修改i的值,队头元素出队,改变i值?
- EdgeNode *e = G->adjList[i].firstedge; //i顶点的邻接链表的第一个结点
- while(e){//e存在时,将e的所有邻接点加入队列,也就是遍历i的所有邻接点
- if(!visited[e->adjvex]){ // adjvex是e所表示的结点下标
- visited[e->adjvex] = 1;
- printf("%d ", G->adjList[e->adjvex].data);//输出顶点下标的数值
- fprintf(fp,"%d ", G->adjList[e->adjvex].data);//输出顶点下标的数值
- EnQueue(Q, e->adjvex); //将该结点入队
- }
- e = e->next; //遍历i的下一个邻接点
- }
- }
-
- printf("\n");
- fclose(fp);
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。