图、邻接表表示法、深度遍历,广度遍历

/*图的邻接表表示法 代码直接提用!*/
//真的要十分小心,本代码出现了少加上&,就查了我许久的bug!!!
/*一个顶点数组 这个数组不仅要存储顶点的信息,还需要存储指向第一个邻接点的指针(单链表)*/
/*分顶点表顶点,和边表结点 */
/*没事千万不要重复给一个申请动态空间 我可以差不多查了一小时的bug*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>//Sleep()函数,system()函数;等
#define  MaxVertices 100

typedef int Boolean;
Boolean visited[MaxVertices];

typedef char DataType;//注意是char类型 队列
typedef struct cirQueue{
	DataType data[MaxVertices];
	int rear;
	int front;
	int count;//记录个数的
}CirQueue;
CirQueue *Q;

typedef struct node{   //边表 
   int adjvex; //记录下标
   node *next;
   int weight;//做为权值
}EdgeNode;
  
typedef struct{     //顶点表  
   char vertex; //顶点内储存数值
   EdgeNode *edgenext;  //边表头指针(其实还是当前的位置)
}VertexNode,AdjList[MaxVertices];
  
  
typedef struct{
    AdjList adjlist;
    int n; //当前顶点数
	int e; //当前边数
}AdjMatrix;

void CreateGraph(AdjMatrix *G);
void DispGraph(AdjMatrix *G);
void menu(void);
void InitQueue(CirQueue);
int EnQueue(CirQueue *Q,DataType x);
DataType DeQueue(CirQueue *Q);
void BFSTraverse(AdjMatrix *G);
void DFS(AdjMatrix *G,int i);
void DFSTraverse(AdjMatrix *G);
int QueueEmpty(CirQueue *Q);
int QueueFull(CirQueue *Q);

int main(void)
{
	int choose=-1,  i1;
	system("color F1");
	system("pause");
	AdjMatrix *G;
	Q=(CirQueue *)malloc(sizeof(CirQueue));
	G=(AdjMatrix *)malloc(sizeof(AdjMatrix));
	menu();
	while(choose!=4)
	{
		printf("\n请选择功能:");
		scanf("%d",&choose);
		switch(choose)
		{
		case 1:
			CreateGraph(G);
			printf("\n建立完成\n");
			break;
		case 2:
			DispGraph(G);
			break;
		case 3:
			printf("\n请输入(Vi,Vj)的下标:Vi:");
			scanf("%d",&i1);
			printf("->");
			while(1)
			{
				if(G->adjlist[i1].edgenext == NULL)//跳出跳出条件是到了无数据读取的地方
				{
            		printf("\n^^^^^于此处结束^^^^^\n");
					break;
				}
				printf("%d(权值:%d)->",G->adjlist[i1].edgenext->adjvex,G->adjlist[i1].edgenext->weight); //->就做中间的一个连接符号
				G->adjlist[i1].edgenext=G->adjlist[i1].edgenext->next;  //此行代码就像以前的P=P->next; 跳到下一条
			}
			printf("\n");
			break;
		case 4:
			printf("\n程序结束,祝您生活愉快!\n");
			exit(0);
		case 5:
			printf("\n即将清屏\n");
			Sleep(1000);
			system("cls");
			menu();
			break;
		case 6:
			puts("深度遍历为:");
			DFSTraverse(G);
			break;
		case 7:
			puts("广度遍历为:");
			BFSTraverse(G);
			break;
		default :
			printf("\n输入有误!请重新输入!\n");
		}
	}
	return 0;
}

void CreateGraph(AdjMatrix *G)
{
    int i,j,k;
    EdgeNode *s;
    printf("输入顶点数和边数(中间以空格分开):");
    scanf("%d %d",&G->n,&G->e);
    printf("建立顶点表\n");
	//此时已经知道了顶点数和边数
    for (i=0; i<G->n; i++)
    {
		printf("请输入第%d个顶点的信息,它的下标为%d :",i+1,i);
		//G->adjlist[i].vertex=getchar();//等价于scanf("%d",&G->adjlist[i].vertex);
		getchar();//读取回车
		scanf("%c",&G->adjlist[i].vertex);
		G->adjlist[i].edgenext=NULL;  //表在还没有使用的时候一般都是置空化
    }
	//前插法 (先后再前)
    printf("建立边表\n");
    for (k=0;k<G->e;k++)  //此时还需加入输入权值的weight,拥有几条边就会要求输入几次
    {
		//此处其实流了两种方法,前面直接的就需要反着输入,1输0,0输1,而后面的间接的就可以直接
		//因为前面的将本该处于后面的j放在了前面
       printf("输入有连接的顶点序号(以做下标)(用空格隔开):");
       scanf("%d %d",&i,&j);
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=j;//边表赋值 
	   printf("\n请输入权值:");
	   scanf("%d",&s->weight);//就是忘记加上&了!!
       s->next=G->adjlist[i].edgenext;  
       G->adjlist[i].edgenext=s;  
       /*s=(EdgeNode *)malloc(sizeof(EdgeNode));
       s->adjvex=i;
	   printf("\n请输入权值:");
	   scanf("%d",&s->weight);//就是忘记加上&了!!!
       s->next=G->adjlist[j].edgenext;//这一行代码到底有没有实现自己该实现的功能
       G->adjlist[j].edgenext=s;*/
    }  
}

void DispGraph(AdjMatrix *G)
{
	AdjMatrix *G1;
	G1=(AdjMatrix *)malloc(sizeof(AdjMatrix));
	int i;
	for (i=0;i<G->n;i++)  
    {
        printf("%d->",i);  //表示第几个
		//此行代码等价于上面一行的代码 printf("\n第%d个是:",i+1);
		G1->adjlist[i].edgenext=G->adjlist[i].edgenext;//用G1来储存初始值
        while(1)
        {
			if(G->adjlist[i].edgenext==NULL)//跳出跳出条件是到了无数据读取的地方
            {
				//此行代码的bug:每次都是以G->adjlist[i].edgenext=NULL才停止,导致下次不好使用,得改
            	printf("\n^^^^^于此处结束^^^^^\n");
				break;
			}
            printf("%d(权值:%d)->",G->adjlist[i].edgenext->adjvex,G->adjlist[i].edgenext->weight); //->就做中间的一个连接符号
            G->adjlist[i].edgenext=G->adjlist[i].edgenext->next;  //此行代码就像以前的P=P->next; 跳到下一条
        }
		G->adjlist[i].edgenext=G1->adjlist[i].edgenext;//变回
        printf("\n");
    }
}

void menu(void)//菜单
{
	printf("\n 1.建立图		2.输出图内关系 \n");
	printf("\n 3.特意查询		4.退出 \n");
	printf("\n 5.清屏			6.深度优先递归算法 \n");
	printf("\n 7.广度优先遍历 \n");
}

void InitQueue(CirQueue *Q)//置队空
{
	Q->front=Q->rear=0;
	Q->count=0;
}

int QueueFull(CirQueue *Q)//判断队列是否已经满了
{
	return Q->count==MaxVertices;
}

int QueueEmpty(CirQueue *Q)//判断队列是否为空
{
	return Q->count==0;
}

int EnQueue(CirQueue *Q,DataType x)//入队
{
	//首先判断队列是否已满
	if(QueueFull(Q))
	{
		printf("\n不好意思,队列已经满了,无法进行入队操作\n");
		return 0;
	}
	Q->count++;
	Q->data[Q->rear]=x;
	Q->rear=(Q->rear+1)%MaxVertices;
	return 1;
}

DataType DeQueue(CirQueue *Q)//出队
{
	//首先需要判断队列是否为空
	DataType temp;
	if(QueueEmpty(Q))
	{
		printf("\n不好意思,队列为空,无法进行出队操作\n");
		return 0;
	}
	Q->count--;
	temp=Q->data[Q->front];
	Q->front=(Q->front+1)%MaxVertices;
	return temp;
}

void BFSTraverse(AdjMatrix *G) //广度遍历
{
	int i=0, j=0;
	EdgeNode *p;
	AdjMatrix *G2;
	G2=(AdjMatrix *)malloc(sizeof(AdjMatrix));
	//printf("第一个G->n=%d\n",G->n);//发现此处G->n的存储出现了问题
	for(j=0; j<G->n; ++j)
		visited[j]=FALSE;
	InitQueue(Q);
	//此处的初始化已经过了,是for循环出现了问题
	for(i=0; i<G->n; ++i)
	{
		G2->adjlist[i].edgenext=G->adjlist[i].edgenext;//保留初始值
		if(!visited[i])
		{
			visited[i]=TRUE;
			printf("%c\t",G->adjlist[i].vertex);
			EnQueue(Q,i);
			while(!QueueEmpty(Q))
			{
				DeQueue(Q);
				p=G->adjlist[i].edgenext;
				while(p)
				{
					if(!visited[p->adjvex])
					{
						visited[p->adjvex]=TRUE;
						printf("%c\t",G->adjlist[p->adjvex].vertex);
						EnQueue(Q,p->adjvex);
					}
					p=p->next;
				}
			}
		}
		G->adjlist[i].edgenext=G2->adjlist[i].edgenext;//变回
	}
}

void DFS(AdjMatrix *G,int i) //深度遍历
{
	AdjMatrix *G1;
	G1=(AdjMatrix *)malloc(sizeof(AdjMatrix));
	EdgeNode *p;
	p=(EdgeNode *)malloc(sizeof(EdgeNode));
	visited[i]=TRUE;
	printf("%c\t",G->adjlist[i].vertex);
	p=G->adjlist[i].edgenext;
	G1->adjlist[i].edgenext=G->adjlist[i].edgenext;//保存初始值
	while(p)
	{
		if(!visited[p->adjvex])
			DFS(G,p->adjvex);
		p=p->next;
	}
	G->adjlist[i].edgenext=G1->adjlist[i].edgenext;//变回
}

void DFSTraverse(AdjMatrix *G) //深度遍历
{
	int i;
	for(i=0; i<G->n; ++i)
		visited[i]=FALSE;//先全为未访问状态
	for(i=0; i<G->n; ++i)
		if(!visited[i]) //找遍即是
			DFS(G,i);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值