主题:哪有比较好的图的实现,包括遍历等算法的实现,谢谢
Youngspirit
[专家分:0] 发布于 2006-12-14 08:18:00
哪有比较好的图的实现,包括遍历等算法的实现,谢谢
板凳
leolhc [专家分:430] 发布于 2006-12-14 10:32:00
哈哈,放给你了,程序写得并不好,我也是初学者,呵呵。
程序保存为.c文件,vc下测试通过
//该程序已实现图的创建,深度优先搜索,广度优先搜索,数据结构采用邻接表
#include<stdio.h>
#include<malloc.h>
#define MAXN 100
typedef struct G_edge //边
{
int adj; //与头结点相接的结点的下标
int weight; //边的权
struct G_edge *next;
}G_edge,*Gedge;
typedef struct G_node //顶点
{
char data;
struct G_edge *next; //指向边
}G_node,*Gnode;
typedef struct G_gra //图结构,包括顶点数组和顶点、边数目
{
G_node Gnode[MAXN];
int n_sum,e_sum;
}G_gra,*Ggra;
typedef struct Q_node
{
G_node *data;
struct Q_node *next;
}Q_node,*Qnode;
typedef struct Q_head
{
Qnode front,rear;
}Q_head,*Qhead;
Qhead ini_Queen(Qhead Q)
{
Q=(Qhead)malloc(sizeof(Q_head));
Q->front=Q->rear=NULL;
return Q;
}
void en_Queen(Qhead Q,Gnode gnode)
{
Qnode q;
q=(Qnode)malloc(sizeof(Q_node));
q->data=gnode;
q->next=NULL;
if (Q->front==NULL)
Q->front=Q->rear=q;
else
{
Q->rear->next=q;
Q->rear=q;
}
}
Qnode de_Queen(Qhead Q)
{
Qnode q=NULL;
if (Q->front==NULL) return NULL;
q=Q->front;
if (Q->front==Q->rear)
Q->front=Q->rear=NULL;
else
Q->front=Q->front->next;
q->next=NULL;
return q;
}
int is_empty_Queen(Qhead Q)
{
if (Q->front==NULL) return 1;
return 0;
}
void ini_Gra(Ggra Gra,int n)//图的初始化
{
int i;
for (i=0;i<n;i++)
{
Gra->Gnode[i].data=' ';
Gra->Gnode[i].next=NULL;
}
Gra->e_sum=0;
Gra->n_sum=0;
}
void print_Gnode(Ggra Gra,int n)//输出所有顶点
{
int i;
printf("Gnode info\n");
printf("Gnode sum=%d\n",Gra->n_sum);
for (i=0;i<n;i++)
{
printf("%4c",Gra->Gnode[i].data);
if ((i+1)%10==0)
printf("\n");
}
printf("\n");
}
int crt_Gnode(Ggra Gra,char node)//建立图顶点
//return 0,1,-1分别表示已有该顶点,成功插入顶点,已经超过最大插入下标
{
int i=0;
while(i<Gra->n_sum && node!=Gra->Gnode[i].data)
i++;
if (node==Gra->Gnode[i].data) return 0;
else if (i>=MAXN) return -1;
else
{
Gra->Gnode[i].data=node;
Gra->n_sum++;
return 1;
}
}
[color=FF0000]竟然放不下,需要分2、3楼[/color]
3 楼
leolhc [专家分:430] 发布于 2006-12-14 10:32:00
int crt_Gedge(Ggra Gra,char from,char to,int weight)
//return 0,1,-1,-2-3分别表示from与to相等,成功加入边
//找不到from,找不到to,已有该边
{
int i=0,j=0;
Gedge pre=NULL,p=NULL;
Gedge s;
if (from==to) return 0;
while(Gra->Gnode[i].data!=from && i<Gra->n_sum-1)
i++;
if (i>=Gra->n_sum) return -1;
while(Gra->Gnode[j].data!=to && j<Gra->n_sum-1)
j++;
if (j>=Gra->n_sum) return -2;
pre=p=Gra->Gnode[i].next;
//下面对首结点进行处理
if (!p||j<p->adj) //当p空或者p非空但j<p->adj
{
s=(Gedge)malloc(sizeof(G_edge));
s->adj=j;s->next=p;s->weight=weight;
Gra->Gnode[i].next=s;
Gra->e_sum++;
return 1;
}
if (j==p->adj)return -3;//p非空且j==p->adj
p=p->next;
//以上完成首结点的处理,下面对后继结点处理
while(p&&j>p->adj)
{
pre=p;
p=p->next;
}
if (!p||j<p->adj)
{
s=(Gedge)malloc(sizeof(G_edge));
s->adj=j;s->next=p;s->weight=weight;
pre->next=s;
Gra->e_sum++;
return 1;
}
return -3;
}
void print_Gedge(Ggra Gra)
{
int i;
Gedge p;
for(i=0;i<Gra->n_sum;i++)
{
printf("%c: ",Gra->Gnode[i].data);
p=Gra->Gnode[i].next;
while(p)
{
printf("%c-->%c(%d) ",Gra->Gnode[i].data,Gra->Gnode[p->adj].data,p->weight);
p=p->next;
}
printf("\n");
}
printf("\n");
}
//深度优先
void DFS(Ggra Gra,int visited[],int i)
{
Gedge e;
visited[i]=1;
printf("%c ",Gra->Gnode[i].data);
e=Gra->Gnode[i].next;
while(e)
{
if (!visited[e->adj])
DFS(Gra,visited,e->adj);
e=e->next;
}
}
//深度优先
void traverDFS(Ggra Gra)
{
int i,visited[MAXN]={0};
for (i=0;i<Gra->n_sum;i++)
{
if (!visited[i])
DFS(Gra,visited,i);
}
printf("\n");
}
//广度优先
void BFS(Ggra Gra,int visited[],int i)
{
Gedge e;
Qnode q;
Qhead Q=NULL;
Q=ini_Queen(Q);
visited[i]=1;
printf("%c ",Gra->Gnode[i].data);//相当于visit下标为i的顶点
en_Queen(Q,&(Gra->Gnode[i]));
while(!is_empty_Queen(Q))
{
q=de_Queen(Q);
e=q->data->next;
q->data=NULL;
free(q);
while(e)
{
if (!visited[e->adj])
{
visited[e->adj]=1;
printf("%c ",Gra->Gnode[e->adj].data);//相当于visit下标为i的顶点
en_Queen(Q,&(Gra->Gnode[e->adj]));
}
e=e->next;
}
}
free(Q);
}
//广度优先
void traverBFS(Ggra Gra)
{
int i,visited[MAXN]={0};
for (i=0;i<Gra->n_sum;i++)
{
if (!visited[i])
BFS(Gra,visited,i);
}
printf("\n");
}
int main()
{
char x,from,to;
int weight;
G_gra Gra;
ini_Gra(&Gra,MAXN);
printf("Please input nodes(Char type, no spaces): \n");
scanf("%c",&x);
while(x!=10)//35是#的ascii码,10是回车
{
crt_Gnode(&Gra,x);
scanf("%c",&x);
}
print_Gnode(&Gra,Gra.n_sum);
printf("Please input from,to and weight: \n");
fflush(stdin);//清除缓存的字符
scanf("%c,%c,%d;",&from,&to,&weight);//输入格式,如:a,b,3;c,d,6;
while(from!=10)
{
crt_Gedge(&Gra,from,to,weight);
scanf("%c,%c,%d;",&from,&to,&weight);
}
print_Gedge(&Gra);
traverDFS(&Gra);
traverBFS(&Gra);
}
测试数据:
输入12345678回车
输入1,2,1;1,3,1;2,4,1;2,5,1;3,6,1;3,7,1;4,8,1;5,8,1;6,7,1;回车再回车