各种基本算法实现小结(四)—— 图及其遍历
(均已测试通过)
====================================================================
图——深度优先和广度优先算法
无向图用二维邻接矩阵表示
测试环境:VC 6.0 (C)
#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define INFINITY 32767#define MAX_VEX 20#define QUEUE_SIZE (MAX_VERTEX+1)#define DataType char /* vertext's info */int *visited; /* Node: visited flag with dynamic array, good idea ! *//* init queue for bfs */struct _node{ int v_num; struct _node *next;};typedef struct _node node, *pnode;struct _queue{ pnode front; pnode rear;};typedef struct _queue queue, *pqueue;struct _graph{ DataType *vexs; int arcs[MAX_VEX][MAX_VEX]; int vexnum, arcnum;};typedef struct _graph graph, *pgraph;/* operation of queue */queue init_queue(){ queue qu; qu.front=qu.rear=(pnode)malloc(sizeof(node)); if(qu.front == NULL) exit(1); qu.rear->next=NULL; return qu;}void en_queue(pqueue pqu, int v_num){ pnode pn; pn=(pnode)malloc(sizeof(node)); if(pqu->front == NULL) exit(1); pn->v_num=v_num; pn->next=NULL; pqu->rear->next=pn; pqu->rear=pqu->rear->next;}int isempty_queue(pqueue pqu){ if(pqu->front == pqu->rear) return 1; else return 0;}int de_queue(pqueue pqu){ pnode pn; int d; if(isempty_queue(pqu)) return -1; pn=pqu->front; d=pn->v_num; pqu->front=pn->next; free(pn); return d;}int locate(graph g, DataType data){ int i; for(i=0;i<g.vexnum;i++) if(g.vexs[i] == data) return i; return -1;}graph create_graph(){ int i,j,w, s1,s2; DataType ch1,ch2,tmp; graph g; printf("g sizeof: %d/n", sizeof(g)); printf("Enter vexnum arcnum:"); scanf("%d %d", &g.vexnum, &g.arcnum); tmp=getchar(); g.vexs=(DataType *)malloc(sizeof(DataType)); if(g.vexs == NULL) exit(1); printf("Enter %d vertext,please.../n", g.vexnum); for(i=0;i<g.vexnum;i++) { printf("vex %d: ", i); scanf("%c", &g.vexs[i]); tmp=getchar(); //visited[i]=0; } for(i=0;i<g.vexnum;i++) for(j=0;j<g.vexnum;j++) g.arcs[i][j]=INFINITY; printf("Enter %d arcs:/n", g.arcnum); for(i=0;i<g.arcnum;i++) { printf("arc %d: ", i); scanf("%c %c %d", &ch1, &ch2, &w); tmp=getchar(); s1=locate(g, ch1); s2=locate(g, ch2); g.arcs[s1][s2]=g.arcs[s2][s1]=w; /* NOTE: weight */ } return g;}int firstvex_graph(graph g, int k){ int i; if(k>=0 && k<g.vexnum) for(i=0;i<g.vexnum;i++) if(g.arcs[k][i] != INFINITY) return i; return -1;}int nextvex_graph(graph g, int i, int j){ int k; if(i>=0 && i<g.vexnum && j>=0 && j<g.vexnum) for(k=j+1; k<g.vexnum; k++) if(g.arcs[i][k] != INFINITY) return k; return -1;}void dfs(graph g, int k){ int i; if(k == -1) { for(i=0;i<g.vexnum;i++) if(!visited[i]) dfs(g,i); } else { visited[k]=1; printf("%c ", g.vexs[k]); for(i=firstvex_graph(g,k);i>=0;i=nextvex_graph(g,k,i)) if(!visited[i]) dfs(g,i); }}void bfs(graph g){ int i,j,k; queue qu; qu=init_queue(); for(i=0;i<g.vexnum;i++) if(!visited[i]) { visited[i] =1; printf("%c ", g.vexs[i]); en_queue(&qu, i); while(!isempty_queue(&qu)) { k=de_queue(&qu); for(j=firstvex_graph(g,k); j>=0;j=nextvex_graph(g,k,j)) if(!visited[j]) { visited[j]=1; printf("%c ", g.vexs[j]); en_queue(&qu, j); } } }}void main(){ int i; graph g; g=create_graph(); visited=(int *)malloc(g.vexnum*sizeof(int)); for(i=0;i<g.vexnum;i++) visited[i]=0; printf("/n/n dfs:"); dfs(g,-1); for(i=0;i<g.vexnum;i++) visited[i]=0; printf("/n bfs:"); bfs(g); if(visited) free(visited); printf("/n");}
运行结果:
======================================================
图——深度优先
测试环境:VS2008 (C)
#include "stdafx.h"#include <stdlib.h>#include <malloc.h>#define MAX_VEX 20#define INFINITY 65535int *visited;struct _node{ int vex_num; struct _node *next;};typedef struct _node node, *pnode;struct _graph{ char *vexs; int arcs[MAX_VEX][MAX_VEX]; int vexnum, arcnum;};typedef struct _graph graph, *pgraph;int locate(graph g, char ch){ int i; for(i=1; i<=g.vexnum; i++) if(g.vexs[i]==ch) return i; return -1;}graph create_graph(){ int i, j, w, p1, p2; char ch1, ch2; graph g; printf("Enter vexnum arcnum: "); scanf("%d %d", &g.vexnum, &g.arcnum); getchar(); for(i=1; i<=g.vexnum; i++) for(j=1; j<g.vexnum; j++) g.arcs[i][j]=INFINITY; g.vexs=(char *)malloc(sizeof(char)); printf("Enter %d vexnum.../n", g.vexnum); for(i=1; i<=g.vexnum; i++) { printf("vex %d: ", i); scanf("%c", &g.vexs[i]); getchar(); } printf("Enter %d arcnum.../n", g.arcnum); for(i=1; i<=g.arcnum; i++) { printf("arc %d: ", i); scanf("%c %c %d", &ch1, &ch2, &w); getchar(); p1=locate(g, ch1); p2=locate(g, ch2); g.arcs[p1][p2]=g.arcs[p2][p1]=w; } return g;}int firstvex_graph(graph g, int i){ int k; if(i>=1 && i<=g.vexnum) for(k=1; k<=g.vexnum; k++) if(g.arcs[i][k]!=INFINITY) return k; return -1;}int nextvex_graph(graph g, int i, int j){ int k; if(i>=1 && i<=g.vexnum && j>=1 && j<=g.vexnum) for(k=j+1; k<=g.vexnum; k++) if(g.arcs[i][k]!=INFINITY) return k; return -1;}void dfs(graph g, int i){ int k, j; if(!visited[i]) { visited[i]=1; printf("%c", g.vexs[i]); for(j=firstvex_graph(g, i); j>=1; j=nextvex_graph(g, i, j)) if(!visited[j]) dfs(g, j); }}void dfs_graph(graph g){ int i; visited=(int *)malloc((g.vexnum+1)*sizeof(int)); for(i=1; i<=g.vexnum; i++) visited[i]=0; for(i=1; i<g.vexnum; i++) if(!visited[i]) dfs(g, i);}int _tmain(int argc, _TCHAR* argv[]){ graph g; g=create_graph(); dfs_graph(g); printf("/n"); return 0;}
======================================================
图——广度优先
测试环境:VS2008 (C)
#include "stdafx.h"#include <stdlib.h>#include <malloc.h>#define MAX_VEX 20#define INFINITY 65535int *visited;struct _node{ int data; struct _node *next;};typedef struct _node node, *pnode;struct _queue{ pnode front; pnode rear;};typedef struct _queue queue, *pqueue;queue init_queue(){ pnode pn=NULL; queue qu; pn=(pnode)malloc(sizeof(node)); if(pn==NULL) printf("init queue, malloc is fail.../n"); pn->data=-1; pn->next=NULL; qu.front=qu.rear=pn; return qu;}int empty_queue(queue qu){ if(qu.rear==qu.front) return 0; else return 1;}void en_queue(pqueue pqu, int data){ pnode pn=NULL; if(pqu->rear==NULL) return; pn=(pnode)malloc(sizeof(node)); pn->data=data; pn->next=pqu->rear->next; pqu->rear->next=pn; pqu->rear=pn;}int de_queue(pqueue pqu){ int data; pnode pn=NULL; if(pqu->front->next==NULL) return -1; pn=pqu->front->next; pqu->front=pqu->front->next; data=pn->data; free(pn); return data;}struct _graph{ char *vexs; int arcs[MAX_VEX][MAX_VEX]; int vexnum, arcnum;};typedef _graph graph, *pgraph;int locate(graph g, char ch){ int i; for(i=1; i<=g.vexnum; i++) if(g.vexs[i]==ch) return i; return -1;}graph create_graph(){ int i, j, w, p1, p2; char ch1, ch2; graph g; printf("Enter vexnum arcnum: "); scanf("%d %d", &g.vexnum, &g.arcnum); getchar(); for(i=1; i<=g.vexnum; i++) for(j=1; j<g.vexnum; j++) g.arcs[i][j]=INFINITY; g.vexs=(char *)malloc((g.vexnum+1)*sizeof(char)); printf("Enter %d vexnum.../n", g.vexnum); for(i=1; i<=g.vexnum; i++) { printf("vex %d: ", i); scanf("%c", &g.vexs[i]); getchar(); } printf("Enter %d arcnum.../n", g.arcnum); for(i=1; i<=g.arcnum; i++) { printf("arc %d: ", i); scanf("%c %c %d", &ch1, &ch2, &w); getchar(); p1=locate(g, ch1); p2=locate(g, ch2); g.arcs[p1][p2]=g.arcs[p2][p1]=w; } return g;}int firstvex_graph(graph g, int i){ int k; if(i>=1 && i<=g.vexnum) for(k=1; k<=g.vexnum; k++) if(g.arcs[i][k]!=INFINITY) return k; return -1;}int nextvex_graph(graph g, int i, int j){ int k; if(i>=1 && i<=g.vexnum && j>=1 && j<=g.vexnum) for(k=j+1; k<=g.vexnum; k++) if(g.arcs[i][k]!=INFINITY) return k; return -1;}void bfs(graph g){ int i, ivex, inextvex; visited=(int *)malloc((g.vexnum+1)*sizeof(int)); for(i=1; i<=g.vexnum; i++) visited[i]=0; queue qu=init_queue(); for(i=1; i<=g.vexnum; i++) { if(!visited[i]) { visited[i]=1; printf("%c", g.vexs[i]); en_queue(&qu, i); } while(!empty_queue(qu)) { ivex=de_queue(&qu); for(inextvex=firstvex_graph(g, ivex); inextvex>=1; inextvex=nextvex_graph(g, ivex, inextvex)) if(!visited[inextvex]) { visited[inextvex]=1; printf("%c", g.vexs[inextvex]); en_queue(&qu, inextvex); } } }}int _tmain(int argc, _TCHAR* argv[]){ graph g; g=create_graph(); bfs(g); printf("/n"); return 0;}
======================================================
图——深度优先和广度优先算法2(网摘)
本文引用网址:http://bbs.bccn.net/thread-155311-1-1.html(编程论坛)
看到本算法在网上转载较多,比较流行,且能直接运行
但发现大多转载中,也把DFS与BFS正好写反了,对此本文已修正
此外,本算法混用了C与C++,不够单纯,申请的指针空间也未及时释放
测试环境:VC 6.0 (C)
#include <stdio.h>#include <malloc.h>#define INFINITY 32767#define MAX_VEX 20 #define QUEUE_SIZE (MAX_VEX+1) bool *visited; typedef struct{ char *vexs; //顶点向量 int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数}Graph;//队列类class Queue{ public: void InitQueue(){ base=(int *)malloc(QUEUE_SIZE*sizeof(int)); front=rear=0;}void EnQueue(int e){ base[rear]=e; rear=(rear+1)%QUEUE_SIZE;}void DeQueue(int &e){ e=base[front]; front=(front+1)%QUEUE_SIZE;}public: int *base; int front; int rear;};//图G中查找元素c的位置int Locate(Graph G,char c){ for(int i=0;i<G.vexnum;i++) if(G.vexs[i]==c) return i; return -1;}//创建无向网void CreateUDN(Graph &G){ int i,j,w,s1,s2; char a,b,temp; printf("输入顶点数和弧数: "); scanf("%d%d",&G.vexnum,&G.arcnum); temp=getchar(); //接收回车 G.vexs=(char *)malloc(G.vexnum*sizeof(char)); //分配顶点数目 printf("输入%d个顶点./n",G.vexnum); for(i=0;i<G.vexnum;i++) //初始化顶点 { printf("输入顶点%d: ",i); scanf("%c",&G.vexs[i]); temp=getchar(); //接收回车 } for(i=0;i<G.vexnum;i++) //初始化邻接矩阵 for(j=0;j<G.vexnum;j++) G.arcs[i][j]=INFINITY; printf("输入%d条弧./n",G.arcnum); for(i=0;i<G.arcnum;i++) { //初始化弧 printf("输入弧%d: ",i); scanf("%c %c %d",&a,&b,&w); //输入一条边依附的顶点和权值 temp=getchar(); //接收回车 s1=Locate(G,a); s2=Locate(G,b); G.arcs[s1][s2]=G.arcs[s2][s1]=w; }}//图G中顶点k的第一个邻接顶点int FirstVex(Graph G,int k){ if(k>=0 && k<G.vexnum) //k合理 for(int i=0;i<G.vexnum;i++) if(G.arcs[k][i]!=INFINITY) return i; return -1;}//图G中顶点i的第j个邻接顶点的下一个邻接顶点int NextVex(Graph G,int i,int j){ if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum) //i,j合理 for(int k=j+1;k<G.vexnum;k++) if(G.arcs[i][k]!=INFINITY) return k; return -1;}//深度优先遍历void DFS(Graph G,int k){ int i; if(k==-1) //第一次执行DFS时,k为-1 { for(i=0;i<G.vexnum;i++) if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS } else { visited[k]=true; printf("%c ",G.vexs[k]); //访问第k个顶点 for(i=FirstVex(G,k);i>=0;i=NextVex(G,k,i)) if(!visited[i]) //对k的尚未访问的邻接顶点i递归调用DFS DFS(G,i); }}//广度优先遍历void BFS(Graph G){ int k; Queue Q; //辅助队列Q Q.InitQueue(); for(int i=0;i<G.vexnum;i++) if(!visited[i]) //i尚未访问 { visited[i]=true; printf("%c ",G.vexs[i]); Q.EnQueue(i); //i入列 while(Q.front!=Q.rear) { Q.DeQueue(k); //队头元素出列并置为k for(int w=FirstVex(G,k);w>=0;w=NextVex(G,k,w)) if(!visited[w]) //w为k的尚未访问的邻接顶点 { visited[w]=true; printf("%c ",G.vexs[w]); Q.EnQueue(w); } } }}//主函数void main(){ int i; Graph G; CreateUDN(G); visited=(bool *)malloc(G.vexnum*sizeof(bool)); printf("/n深度优先遍历: "); for(i=0;i<G.vexnum;i++) visited[i]=false; DFS(G,-1); /* NODE: DFS */ printf("/n广度优先遍历: "); for(i=0;i<G.vexnum;i++) visited[i]=false; BFS(G); /* NODE: BFS */ printf("/n程序结束./n");}
运行结果:
======================================================
#include <iostream.h> #include <stdlib.h> #define INFINITY 0 #define MAX_VERTEX_NUM 10 //最大顶点数 #define MAX_EDGE_NUM 40 //最大边数 typedef enum {DG,DN,UDG,UDN}Graphkind; typedef char VertexType; //顶点数据类型 typedef struct ArcCell { int adj; //无权图,1或0表示相邻否;带权图则是权值。 //int *info; }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct { VertexType vexs[MAX_VERTEX_NUM]; //顶点向量 AdjMatrix arcs; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数。 Graphkind kind; }MGraph; int LocateVex(MGraph G,VertexType v1) { int i; for(i=0;i<G.vexnum;i++) if(G.vexs[i]==v1) return i; return -1; } int CreatUDN(MGraph &G) // 采用数组表示法,构造无向网 G { VertexType v1,v2; int w,j; cout<<"输入图的顶点数"<<endl; cin>>G.vexnum; cout<<"输入图的弧数"<<endl; cin>>G.arcnum; for(int i=0;i<G.vexnum;i++) { cout<<"输入顶点向量"<<endl; cin>>G.vexs[i]; } for(i=0;i<G.vexnum;i++) for(j=0;j<G.vexnum;j++) { G.arcs[i][j].adj=INFINITY; } for(int k=0;k<G.arcnum;++k) //构造邻接矩阵 { cout<<"输入边依附的两个顶点"<<endl; cin>>v1>>v2; cout<<"输入此边的权值"<<endl; cin>>w; i=LocateVex(G,v1); j=LocateVex(G,v2); G.arcs[i][j].adj=w; G.arcs[j][i].adj=G.arcs[i][j].adj; } return 1; } void dispMGraph(MGraph G) { cout<<"图的邻接矩阵图是:"<<endl; for(int i=0;i<G.vexnum;i++) { for(int j=0;j<G.vexnum;j++) cout<<" "<<G.arcs[i][j].adj; cout<<endl; } } void main() { MGraph G; CreatUDN(G); dispMGraph(G); } // 邻接表 表示: #include <iostream.h> #include <stdlib.h> #define MAX_VERTEX_NUM 20 //最大顶点数 #define MAX_EDGE_NUM 40 //最大边数 int visited[ MAX_VERTEX_NUM]; typedef int VertexType ; //顶点数据类型 typedef struct ArcNode { int adjvex; int weight; struct ArcNode *nextarc; }ArcNode; typedef struct VNode { VertexType data; ArcNode *firstarc; }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; int vexnum,arcnum; int kind; }ALGraph; void CreateDG(ALGraph &G) { int i,j,k; ArcNode *p; cout<<"创建一个图:"<<endl; cout<<"顶点数:"; cin>>G.vexnum;cout<<endl; cout<<"边数:"; cin>>G.arcnum; cout<<endl; for(i=0;i<G.vexnum;i++) { G.vertices[i].data=i; G.vertices[i].firstarc=NULL; } for(k=0;k<G.arcnum;k++) { cout<<"请输入第"<<k+1<<"条边:"; cin>>i>>j; p=(ArcNode*)malloc(sizeof(ArcNode)); p->adjvex=j; p->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p; } } void Disp(ALGraph G) { int i,j; ArcNode *p; cout<<"输出图为:"<<endl; for(i=0;i<G.vexnum;i++) { p=G.vertices[i].firstarc; j=0; while(p!=NULL) { cout<<"("<<i<<","<<p->adjvex<<")"; p=p->nextarc; j=1; } if(j==1) cout<<endl; } } void dfs(ALGraph G,int v) //深度优先遍历 { ArcNode *p; cout<<v<<" "; visited[v]=1; p=G.vertices[v].firstarc; while(p!=NULL) { if(!visited[p->adjvex]) dfs(G,p->adjvex); p=p->nextarc; } return ; } void dfs1(ALGraph G) { int i; for(i=0;i<G.vexnum;i++) if(visited[i]==0) dfs(G,i); } void main() { ALGraph G; CreateDG(G); int v; Disp(G); cout<<"输入顶点:"; cin>>v; cout<<"深度优先序列:"; dfs1(G); cout<<endl; }
参考推荐:
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow