建立一个包含6个结点的有向图的邻接表,实现插入、删除边的功能,并进行深度优先遍历和广度优先遍历。

#include<stdio.h>
#include<stdlib.h>
#define MAX_VERTEX_NUM 20
#define UNVISITED 0
#define VISITED 1
typedef struct Arcnode
{
	int adjvex;                //adjvex指的是结点的下标
	struct Arcnode *nextarc;
	int weight;
}Arcnode;

typedef struct Vnode
{
	char data;
	Arcnode *firstarc;
}Vnode;

typedef struct
{
	Vnode vertexs[MAX_VERTEX_NUM];
	int vernum,arcnum;
}ALGraph;

//队列基本操作
typedef struct node
{
	int data[MAX_VERTEX_NUM];
	int front,rear;
}Queue;

void Init(Queue &q)//队列初始化
{
	q.front=q.rear=0;
}

int InQueue(Queue &q,int n)//进队
{
	if((q.rear+1)%MAX_VERTEX_NUM==q.front)
		return 0;
	q.data[q.rear]=n;
	q.rear=(q.rear+1)%MAX_VERTEX_NUM;
	return 1;
}

int Empty(Queue q)//判断队是否为空
{
	if(q.front==q.rear)
		return 1;
	else
		return 0;
}
int DelQueue(Queue &q,int &n)//出队
{
	if(q.front==q.rear)
		return 0;
	n=q.data[q.front];
	q.front=(q.front+1)%MAX_VERTEX_NUM;
	return 1;
}


int Locate(ALGraph g,char v)
{
	int i;
	for(i=0;i<g.vernum;i++)
	{
		if(g.vertexs[i].data==v)
			return i;
	}
}
void CreatALGraph(ALGraph &g)           //创建邻接表
{
	int i;
	int num1,num2;
	char v1,v2;
	Arcnode *s;
	printf("请输入邻接表的顶点个数及边数:");
	scanf("%d %d",&g.vernum,&g.arcnum);
	for(i=0;i<g.vernum;i++)
	{
		getchar();
		printf("输入顶点%d信息:",i+1);
		scanf("%c",&g.vertexs[i].data);
		g.vertexs[i].firstarc=NULL;
	}

	for(i=0;i<g.arcnum;i++)
	{
		getchar();
		printf("请输入第%d个边的信息(顶点-顶点-弧):",i+1);
		scanf("%c %c",&v1,&v2);
		num1=Locate(g,v1);
		num2=Locate(g,v2);
		s=(Arcnode*)malloc(sizeof(Arcnode));
		s->adjvex=num2;
		s->nextarc=g.vertexs[num1].firstarc;
		g.vertexs[num1].firstarc=s;

	}
}

int visited[MAX_VERTEX_NUM]={UNVISITED};

void DFS(ALGraph g,int v)
{
	Arcnode *p;
	visited[v]=VISITED;
	p=g.vertexs[v].firstarc;
	printf("%c  ",g.vertexs[v].data);
	while(p!=NULL)
	{
		if(visited[p->adjvex]==UNVISITED)
		{
			DFS(g,p->adjvex);
		}
		p=p->nextarc;
	}

}

void DFSTrsverse(ALGraph g)
{
	int v;
	for(v=0;v<g.vernum;v++)
	{
		if(visited[v]==UNVISITED)
			DFS(g,v);
	}
}

int visit[MAX_VERTEX_NUM]={0};
void BFSTraverse(ALGraph g,int v0)
{
	int v;
	Arcnode *p;
	Queue q;
	Init(q);
	printf("%3c",g.vertexs[v0].data);
	visit[v0]=VISITED;
	InQueue(q,v0);
	while(!Empty(q))
	{
		DelQueue(q,v);
		p=g.vertexs[v].firstarc;
		while(p!=NULL)
		{
			if(visit[p->adjvex]==UNVISITED)
			{
				printf("%3c",g.vertexs[p->adjvex].data);
			    visit[p->adjvex]=VISITED;
				InQueue(q,p->adjvex);
			}
			p=p->nextarc;
		}
	}
}
void Print(ALGraph g)
{
	int i;
	Arcnode *p;
	printf("图的邻接表表示:");
	for(i=0;i<g.vernum;i++)
	{
		p=g.vertexs[i].firstarc;
		printf("\n%4c",g.vertexs[i].data);
		while(p!=NULL)
		{
			printf("-->%c",g.vertexs[p->adjvex].data);
		    p=p->nextarc;
		}
		printf("\n");
	}

}

void Insert(ALGraph &g)
{
	char v1,v2;
	int num1,num2;
	getchar();
	printf("请输入想要插入的顶点(顶点-顶点):");
	scanf("%c %c",&v1,&v2);
	Arcnode *p;
	num1=Locate(g,v1);
	num2=Locate(g,v2);
	p=(Arcnode*)malloc(sizeof(Arcnode));
	p->adjvex=num2;
	p->nextarc=g.vertexs[num1].firstarc;
	g.vertexs[num1].firstarc=p;
}

void Del(ALGraph &g)
{
	char v1,v2;
	int num1;
	Arcnode *p,*q;
	Arcnode *s;
	getchar();
	printf("请输入想要删除的顶点(顶点-顶点):");
	scanf("%c %c",&v1,&v2);
	num1=Locate(g,v1);
	p=g.vertexs[num1].firstarc;
	while(p!=NULL)
	{
		if(g.vertexs[p->adjvex].data==v2)
			break;
		q=p;
		p=p->nextarc;
	}
	s=p;
	q->nextarc=p->nextarc;
	free(s);

}
void main()
{
	int n;
	int v0;
	ALGraph g;
	while(1)
	{
	    printf("\n请输入想要进行的操作:");
	    scanf("%d",&n);
	    switch(n)
		{
	    case 1:
		    CreatALGraph(g);
		    break;
	    case 2:
		    DFSTrsverse(g);
		    break;
		case 3:
			printf("输入想要访问的结点:");
			scanf("%d",&v0);
			BFSTraverse(g,v0-1);
			break;
		case 4:
			Insert(g);
			break;
		case 5:
			Del(g);
			break;
	    case 6:
	 	    Print(g);
		    break;
		}
	}

}``

遇到的问题:1.邻接表中用到的结构体较多。
2.创建链表里面的adjvex指的是结点下标,是int型,不是char 型。
3.注意scanf %c和getchar();!!!!!
4.删除操作g.vertexs[p->adjvex].data==v2这一句是:g.vertexs[p->adjvex].data==v2,而不是g.vertexs[p->adjvex].data==‘v2’。
5.Print里面---->多学习。
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值