各种基本算法实现小结(四)—— 图及其遍历
(均已测试通过)
====================================================================
图——深度优先和广度优先算法
无向图用二维邻接矩阵表示
测试环境: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 65535
int *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 65535
int *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;
}
参考推荐: