C语言 数据结构 图的储存、遍历、简单应用
内容:
1,创建图(邻接矩阵和邻接链表两种方法)
2,图的深度和广度优先搜索结果
3,判断图是否为连通图
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MVNum 100
#define MAXSIZE 100
typedef char VerTexType;
typedef int ArcType;
typedef int QELemType;
typedef struct{
VerTexType vexs[MVNum];
ArcType arc[MVNum][MVNum];
int vexnum,arcnum;
} AMGragh;
int LocationVex(AMGragh *G,int num);
int CreateUDN(AMGragh *G);
void showGragh(AMGragh *G);
typedef struct ArcNode{
int adjVex;
struct ArcNode *nextarc;
int info;
}ArcNode;
typedef struct VNode{
VerTexType data;
ArcNode *firstarc;
}VNode,AdjList;
typedef struct{
VNode vertices[MVNum];
int vexnum,arcnum;
}ALGragh;
int LLocationVex(ALGragh *G,int num);
int CreateUDG_L(ALGragh *G);
void showGragh_L(ALGragh *G);
void DFS(ALGragh *G, int v0);
void BFS(ALGragh *G, int v0);
void TraverseG(ALGragh *G);
int connect(ALGragh *G);
void pathdfs(ALGragh *G,int i,int j);
typedef struct{
QELemType data[MAXSIZE];
int front;
int rear;
}SqQueue;
void InitQueue(SqQueue *Q){
Q->front=0;
Q->rear=0;
}
int QueueEmpty(SqQueue *Q){
if(Q->front==Q->rear)
return 1;
return 0;
}
int EnQueue(SqQueue *Q,QELemType e){
if((Q->rear+1)%MAXSIZE==Q->front)
return -1;
Q->data[Q->rear]=e;
Q->rear=(Q->rear+1)%MAXSIZE;
return 0;
}
int DeQueue(SqQueue *Q,QELemType *e){
if(Q->front==Q->rear)
return -1;
*e=Q->data[Q->front];
Q->front=(Q->front+1)%MAXSIZE;
return 0;
}
int main(){
printf("请选择存储方式:1-邻接矩阵存储 2-邻接表存储");
int key;
scanf("%d",&key);
switch(key){
case 1:{
AMGragh G;
CreateUDN(&G);
showGragh(&G);
break;
}
case 2:{
ALGragh G;
CreateUDG_L(&G);
showGragh_L(&G);
int num=connect(&G);
if(num==1) printf("\n该图为连通图\n");
else printf("\n该图不连通\n");
int num1, num2,i,j;
printf("请输入两个元素:");
scanf("%d %d", &num1, &num2);
i=LLocation(&G,num1);
i=LLocation(&G,num1);
printf("简单路径为:");
pathdfs(graph, i, j);
printf("\n");
break;
}
}
}
void pathdfs(ALGragh *G,int i,int j){
EdgeNode *p;
int s,w;
visited[i] = 1;
path[++top] = G->list[i].data;
if(!flag && path[top] == G->list[j].data) {
flag = 1;
}
if(flag)
{
printf("\n");
for(s=1;s<=top;s++)
printf("%d\t",path[s]);
flag = 0;
}
else
for(p = G->list[i].firstEdge; p; p = p->next)
{
w = p->indexVertex;
if(!visited[w])
pathdfs(G,w,j);
}
visited[i]=0;
top--;
}
int CreateUDG_L(ALGragh *G){
int v1,v2;
int num,i,j;
printf("请输入总顶点和总边数:");
scanf("%d %d",&G->vexnum,&G->arcnum);
for(int l=0;l<G->vexnum;l++){
scanf("%d",&G->vertices[l].data);
G->vertices[l].firstarc=NULL;
}
printf("请输入一条边所依附的顶点及边的权值\n");
for(int k=0;k<G->arcnum;k++){
scanf("%d %d %d",&v1,&v2,&num);
i=LLocationVex(G,v1);
j=LLocationVex(G,v2);
ArcNode *p1=(ArcNode *)malloc(sizeof(struct ArcNode));
p1->adjVex=j;
p1->info=num;
p1->nextarc=G->vertices[i].firstarc;
G->vertices[i].firstarc=p1;
ArcNode *p2=(ArcNode *)malloc(sizeof(ArcNode));
p2->adjVex=i;
p2->info=num;
p2->nextarc=G->vertices[j].firstarc;
G->vertices[j].firstarc=p2;
}
}
int LLocationVex(ALGragh *G,int num){
int i;
for(i=0;i<G->vexnum;i++){
if(G->vertices[i].data==num){
break;
}
}
return i;
}
void showGragh_L(ALGragh *G){
printf("邻接表储存:\n");
for(int i=0;i<G->vexnum;i++){
printf("%d ->",G->vertices[i].data);
for(ArcNode *j=G->vertices[i].firstarc;j!=NULL;j=j->nextarc){
printf("%d ",G->vertices[j->adjVex].data);
}
printf("\n");
}
printf("\n");
TraverseG(G);
}
int visited[MVNum]={0};
void DFS(ALGragh *G, int v0){
printf("%d",G->vertices[v0].data);
visited[v0]=1;
ArcNode *p=G->vertices[v0].firstarc;
while(p!=NULL){
if(!visited[p->adjVex]){
DFS(G,p->adjVex);
}
p=p->nextarc;
}
}
void BFS(ALGragh *G, int v0){
QELemType u;
printf("%d",G->vertices[v0].data);
visited[v0]=1;
SqQueue Q;
InitQueue(&Q);
EnQueue(&Q,v0);
while(!QueueEmpty){
DeQueue(&Q,&u);
for(ArcNode *w=G->vertices[v0].firstarc;w!=NULL;w=w->nextarc) {
if(!visited[w->adjVex]){
printf("%d ",G->vertices[w->adjVex].data);
visited[w->adjVex]=1;
EnQueue(&Q,w->adjVex);
}
}
}
printf("\n\n");
}
void TraverseG(ALGragh *G){
int v;
printf("\n深度优先搜索遍历图的结果 :");
for(v=0;v<G->vexnum;v++) visited[v]=0;
for(v=0;v<G->vexnum;v++)
if(!visited[v])
DFS(G,v);
printf("\n广度优先搜索遍历图的结果 :");
for(v=0;v<G->vexnum;v++) visited[v]=0;
for(v=0;v<G->vexnum;v++)
if(!visited[v])
BFS(G,v);
}
int connect(ALGragh *G) {
int count=0;
for(int v=0;v<G->vexnum;v++) visited[v]=0;
for(int v=0;v<G->vexnum;v++)
if(!visited[v]){
DFS(G,v);
count++;
}
printf("\n\n");
return count;
}
void showGragh(AMGragh *G){
for(int i=0;i<G->vexnum;i++){
printf("%d",G->vexs[i]);
}
printf("\n");
for(int i=0;i<G->vexnum;i++){
for(int j=0;j<G->vexnum;j++){
printf("%d ",G->arc[i][j]);
}
printf("\n");
}
}
int LocationVex(AMGragh *G,int num){
int i=0;
for( i=0;i<G->vexnum;i++){
if(G->vexs[i]==num){
break;
}
}
return i;
}
int CreateUDN(AMGragh *G){
int i=0,j=0;
printf("请输入总顶点数和总边数:");
scanf("%d %d",&G->vexnum,&G->arcnum);
printf("请输入顶点信息:");
for(i=0;i<G->vexnum;i++){
scanf("%d",&G->vexs[i]);
}
for(i=0;i<G->vexnum;i++){
for(j=0;j<G->vexnum;j++){
G->arc[i][j]=0;
}
}
int k=0,w;
int v1,v2;
printf("请输入一条边所依附的顶点及边的权值\n");
for(k=0;k<G->arcnum;k++){
scanf("%d %d %d",&v1,&v2,&w);
i=LocationVex(G,v1);
j=LocationVex(G,v2);
G->arc[i][j]=w;
G->arc[j][i]=G->arc[i][j];
}
return 0;
}