您的位置:首页 > 编程语言 > C语言/C++

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

2017-09-06 14:22 776 查看
各种基本算法实现小结(四)—— 图及其遍历

(均已测试通过)

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

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

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

测试环境:VC 6.0 (C)

[cpp] view
plain copy

print?

#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)

[cpp] view
plain copy

print?

#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)

[b][cpp] view
plain copy[/b]

print?

#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)

[cpp] view
plain copy

print?

#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");

}

运行结果:





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

[cpp] view
plain copy

print?

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: