各种基本算法实现小结(四)—— 图及其遍历

               

各种基本算法实现小结(四)—— 图及其遍历

(均已测试通过)

====================================================================

图——深度优先和广度优先算法

无向图用二维邻接矩阵表示

测试环境: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

猜你喜欢

转载自blog.csdn.net/dghggij/article/details/86563997
今日推荐