数据结构作业——图

要求

1,创建有向图
2,输出拓扑排序
3,输出深度遍历次序
4,输出广度遍历次序

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int in[maxn];
int f[maxn];
//队列 
typedef struct qnode{
	int x;
	struct qnode *nex;
} qnode,*queueptr;
typedef struct{
	queueptr front;
	queueptr rear;
}linkqueue;

//邻接表 
typedef struct Node{
	int x;
	Node *nex;
} *ve;
/************入队********/ 
void Push(linkqueue &q,int x)
{
	qnode *p; 
	p=new qnode;
	p->x=x;
	p->nex=NULL;
	q.rear->nex=p;
	q.rear=p;
}
/*******************得到对顶元素****************/ 
int Top(linkqueue q)
{
	return q.front->nex->x;
}
/***************出队************************/ 
void Pop(linkqueue &q)
{
	qnode *p;
	p=q.front->nex;
	q.front->nex=p->nex;
	if(q.rear==p) q.rear=q.front;
	delete p;
}
/*****************判空 *******************/
int Empty(linkqueue l)
{
	if(l.front==l.rear) return 1;
	else return 0;
}
/*********************将元素防放入邻接表之中 *******/
void Push(Node &l,int x)
{
	Node *p;
	p=new Node;
	p->nex=l.nex;
	p->x=x;
	l.nex=p;
}
/**************************深度优先搜索***************************** */
void DFS(ve *vec,int x)
{
	Node *now;
	now =new Node;
	now=vec[x]->nex;
	if(f[x]) return ;
	
	f[x]=1;
	while(now!=NULL)                                   //遍历这个节点指向的节点 
	{
		int y=now->x;
		now=now->nex;
		if(f[y]==0) {								  //如果没有标记过输出 
			printf("%d->%d\n",x,y);
			DFS(vec,y);
		} 
	}
}
/*******************************************广度优先搜索************************************************/ 
void BFS(ve *vec,int x)
{
	//初始化队列 
	linkqueue *qu;
	qu=new linkqueue;
	qu->front=qu->rear=new qnode;
	qu->front->nex=NULL;
	
	Push(*qu,x);
	while(Empty(*qu)==0)
	{
		int x=Top(*qu);
		Pop(*qu);
		f[x]=1;
		Node *now;
		now =new Node;
		now=vec[x]->nex;
		while(now!=NULL)//遍历这个节点指向的节点 
		{
			int y=now->x;
			now=now->nex;
			if(f[y]) continue; 
			printf("%d->%d\n",x,y);
			Push(*qu,y);
		}
	}
	delete qu;
}
/******************************** 拓扑排序************************************/	
void tuo_pu(ve *vec,int n,int m)
{
	//初始化队列 
	linkqueue *qu;
	qu=new linkqueue;
	qu->front=qu->rear=new qnode;
	qu->front->nex=NULL;
	 
	for(int i=1;i<=n;i++) if(in[i]==0) Push(*qu,i);             //把入度为零的节点放进队列去 
	int sum=0; 
	
/*******************************开始遍历拓扑序列 ************************************/
	while(Empty(*qu)==0)
	{
		int x=Top(*qu);
		cout<<x<<" ";
		Pop(*qu);
		sum++;
		Node *now;
		now =new Node;
		now=vec[x]->nex;
		while(now!=NULL)										//遍历这个节点指向的节点 
		{
			int y=now->x;
			in[y]--;											//将他指向的节点的入度减 1 
			if(in[y]==0)										//如果为零就放进队列去 
			{
				Push(*qu,y);
			}
			now=now->nex;
		}
	}
	if(sum!=n) puts("剩下的节点有环的出现,请你自习检查!");	//如果sum不等于n那么说明有环的存在 
	else puts("");
	delete qu; 
} 
void chang_jian(ve *vec,int &n,int &m)
{
	int x,y;
	puts("请输入该图一共有 n 个顶点,m 条边,n 和 m 的值:"); 
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){										//初始化邻接表 
		in[i]=0;
		vec[i]=new Node;
		vec[i]->nex=NULL;
	}
	puts("请输入m条边,注意顶点值不能大于n");
	while(m--)													//存边 
	{
		while(1)
		{
			scanf("%d%d",&x,&y);
			if(x>0&&x<=n&&y>0&&y<=n) break;
			else puts("输入数据不合法,超出了范围请重新输入");
		}
		Push(*(vec[x]),y);
		in[y]++;                                               //入度加一 
	}
}
void zhu_cai_dan()
{
	puts("\n 返回主菜单请输输入 1");
	puts(" 创建有向图请输入 2");
	puts(" 进行拓扑排序请输入 3");
	puts(" 进行深度优先搜索请输入 4");
	puts(" 进行广度优先搜索请输入 5");
	puts(" 退出程序请输入 6");
}

int main()
{
	int n,m;
	int x,y;	
	ve vec[1000];//创建邻接表 
	int flag=1; 
	int F=0;
	zhu_cai_dan();
	while(1)
	{
		scanf("%d",&x);
		switch(x)
		{
			case 1: 
					zhu_cai_dan();
					break;
			case 2:
					if(flag==0) {
						puts("你已经创建过有向图了,请进行其他操作");
						break;
					} 
					chang_jian(vec,n,m);
					puts("创建成功"); 
					flag=0;
					break;
			case 3:	
					if(flag) 
					{
						puts("你还为创建有向图请先创建再进行操作谢谢");
						break;
					} 
					tuo_pu(vec,n,m);//拓扑函数 
					break;
			case 4:	
					if(flag) 
					{
						puts("你还为创建有向图请先创建再进行操作谢谢");
						break;
					}
					printf("请输入开始深度遍历的第一个节点是多少 节点大小在1~%d 之间\n",n);
					while(1)
					{
						scanf("%d",&x);
						if(x>0&&x<=n) break;
						else puts("输入数据不合法,超出了范围请重新输入");
					}
					for(int i=1;i<=n;i++) f[i]=0;
 					DFS(vec,x);
					break;
			case 5:	
					if(flag) 
					{
						puts("你还为创建有向图请先创建再进行操作谢谢");
						break;
					}
					printf("请输入开始深度遍历的第一个节点是多少 节点大小在1~%d 之间\n",n);
					while(1)
					{
						scanf("%d",&x);
						if(x>0&&x<=n) break;
						else puts("输入数据不合法,超出了范围请重新输入");
					}
					for(int i=1;i<=n;i++) f[i]=0;
					BFS(vec,x);
					break;
			case 6:	
					F=1;
					puts("感谢老师指导,谢谢使用");
					break;
			defalut:	puts("数据不合法请重新输入");
				
		}
		if(F) break;
	}
	return 0;
}