图-创建-遍历-出入度
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include
#include
#define MAX_V 100 //最大节点数
#define TRUE 1
#define FALSE 0
//定义数据结构
typedef struct node_v
{
int vertex; //节点
char ch; //结点信息
struct node_v *link;
}VNode;
typedef struct
{
VNode *adjlist[MAX_V]; //宣告邻接表
int length; //记录邻接表个数
}ALGraph;
int visited[MAX_V+1]; //记录顶点是否被访问过或记录出入度或记录矩阵一行图
void AdjList(ALGraph *); //邻接表创建
void ReadAdjList(ALGraph *); //数组创建
void show_adjlist(ALGraph); //显示各邻接表的数据
void show_matrix(ALGraph); //显示邻接矩阵
void DFS(ALGraph); //图的深度优先搜索
void DFSL(ALGraph,int); //调用的递归深度优先搜索
void BFS(ALGraph); //图的广度优先搜索
void IO_V(ALGraph); //计算入出度
VNode *searchlast(VNode *); //搜索表组后节点函数
//创建
void AdjList(ALGraph *v)
{
int i,j,vi=1;
char c;
VNode *node,*lnode;
puts("\n输入顶点信息('@'结束)");
while(1)
{//设定数组及各表初始值
printf("\n%d: ",vi);
c=getche();
if(c=='@')
break;
visited[vi]=FALSE;
v->adjlist[vi]=(VNode *)malloc(sizeof(VNode));
v->adjlist[vi]->ch=c;
v->adjlist[vi]->vertex=vi;
v->adjlist[vi]->link=NULL;
vi++;
}
v->length=vi-1;
puts("\n输入指向下一顶点值('@'结束):");
for(i=1;i<=v->length;i++)
{
lnode=v->adjlist[i];
printf("%d:%c- ",i,v->adjlist[i]->ch);
while(1)
{
c=getche();
if(c=='@')
{
printf("\n");
break;
}
for(j=1;j<=v->length;j++)
if(v->adjlist[j]->ch==c)
break; //寻找是输入值是否在邻接表中
if(j>v->length)
{
puts("出错,重新输入");
continue;
}
node=(VNode *)malloc(sizeof(VNode));
node->vertex=j;
node->link=NULL;
node->ch=c;
searchlast(lnode)->link=node;
}
}
}
//读盘创建
void ReadAdjList(ALGraph *v)
{
FILE *fptr;
VNode *node,*lastnode;
int vi,vj,w;
fptr=fopen("DFS.txt","r");
if(fptr==NULL)
{
perror("DFS.txt"); //出错
system("pause");
exit(0);
}
//读取节点总数
fscanf(fptr,"%d",&v->length);
for(vi=1;vi<=v->length;vi++)
{//设定数组及各表初始值
visited[vi]=FALSE;
v->adjlist[vi]=(VNode *)malloc(sizeof(VNode));
v->adjlist[vi]->vertex=vi;
v->adjlist[vi]->ch=(char)'A'+vi-1;
v->adjlist[vi]->link=NULL;
}
//读取节点数据
for(vi=1;vi<=v->length;vi++)
for(vj=1;vj<=v->length;vj++)
{
fscanf(fptr,"%d",&w);
//数据元素以邻接矩阵格式存储,以1代表相邻,0代表不相邻,将相邻顶点连接在表后
if(w!=0)
{
node=(VNode *)malloc(sizeof(VNode));
node->vertex=vj;
node->link=NULL;
lastnode=searchlast(v->adjlist[vi]);
lastnode->link=node;
}
}
fclose(fptr);
}
/* 创建一DFS.txt文件 文件内容如下
10
0 1 1 0 0 0 0 0 0 0
1 0 0 1 1 0 0 0 0 0
1 0 0 0 0 1 1 1 1 1
0
1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 1 0
0 0 1 0 0 0 0 1 1 0
0 0 0 1 1 0 0 0 0 1
0 0 0 0 0 1 1 0 0 1
0 0 0 0 0 0 0 1 1 0
放在同一文件夹下*/
//显示各邻接表的数据
void show_adjlist(ALGraph G)
{
int index;
VNode *ptr;
puts("\n-----邻接表的数据------");
for(index=1;index<=G.length;index++)
{
printf("%c",G.adjlist[index]->ch);
ptr=G.adjlist[index]->link;
while(ptr!=NULL)
{
printf("-->%c",G.adjlist[ptr->vertex]->ch);
ptr=ptr->link;
}
printf("\n");
}
}
//显示邻接矩阵
void show_matrix(ALGraph G)
{
puts("-----数组数据-----");
int i,j;
VNode *ptr;
for(i=1;i<=G.length;i++)
visited[i]=FALSE; //初始化
printf(" ");
for(i=1;i<=G.length;i++)
printf("%c ",G.adjlist[i]->ch);
printf("\n");
for(i=1;i<=G.length;i++)
{
ptr=G.adjlist[i];
printf("%c ",ptr->ch);
ptr=ptr->link;
while(ptr)
{
visited[ptr->vertex]=1;
ptr=ptr->link;
}
for(j=1;j<=G.length;j++)
printf("%d ",visited[j]);
printf("\n");
for(j=1;j<=G.length;j++)
visited[j]=FALSE; //初始化
}
}
//计算出度入度
void IO_V(ALGraph G)
{
int i;
VNode *ptr;
for(i=1;i<=G.length;i++)
visited[i]=FALSE; //初始化
for(i=1;i<=G.length;i++)
{
ptr=G.adjlist[i]->link;
while(ptr)
{
visited[i]++;
ptr=ptr->link;
}
}
puts("-----出度-----");
for(i=1;i<=G.length;i++)
printf("%c(%d)\t",G.adjlist[i]->ch,visited[i]);
for(i=1;i<=G.length;i++)
visited[i]=FALSE; //初始化
for(i=1;i<=G.length;i++)
{
ptr=G.adjlist[i]->link;
while(ptr)
{
visited[ptr->vertex]++;
ptr=ptr->link;
}
}
puts("\n-----入度-----");
for(i=1;i<=G.length;i++)
printf("%c(%d)\t",G.adjlist[i]->ch,visited[i]);
}
//图的深度优先搜索
void DFS(ALGraph G)
{
int k;
char ch;
for(k=1;k<=G.length;k++)
visited[k]=FALSE; //置初值
puts("输入开始遍历节点");
next:
ch=getche();
printf("\n");
for(k=1;k<=G.length;k++)
if(G.adjlist[k]->ch==ch)
break;
if(k>G.length)
{
puts("错误,重新输入遍历节点值");
goto next;
}
else DFSL(G,k);
printf("\n\n");
}
//调用的递归深度优先搜索
void DFSL(ALGraph G,int i)
{
VNode *ptr;
int w;
printf("%c ",G.adjlist[i]->ch);
visited[i]=TRUE; //设定 v 定点为已访问过
ptr=G.adjlist[i]->link; //访问相邻顶点
while(ptr)
{//若顶点尚未访问,则以此顶点为新起点继续做深度优先遍历,否则找其它相邻的顶点,直到所有相连接的节点都已访问
w=ptr->vertex;
if(!visited[w])
DFSL(G,w);
else
ptr=ptr->link;
}
}
#define OK 1
#define OVERFLOW 0
#define ERROR 0
typedef int Status;
typedef int QElemType;
/* c3-2.h 单链队列--队列的链式存储结构 */
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;
Status InitQueue(LinkQueue *Q)
{ /* 构造一个空队列Q */
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if(!(*Q).front)
exit(OVERFLOW);
(*Q).front->next=NULL;
return OK;
}
Status QueueEmpty(LinkQueue Q)
{ /* 若Q为空队列,则返回TRUE,否则返回FALSE */
if(Q.front==Q.rear)
return TRUE;
else
return FALSE;
}
Status EnQueue(LinkQueue *Q,QElemType e)
{ /* 插入元素e为Q的新的队尾元素 */
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
if(!p) /* 存储分配失败 */
exit(OVERFLOW);
p->data=e;
p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
return OK;
}
Status DeQueue(LinkQueue *Q,QElemType *e)
{ /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
QueuePtr p;
if((*Q).front==(*Q).rear)
return ERROR;
p=(*Q).front->next;
*e=p->data;
(*Q).front->next=p->next;
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
return OK;
}
//图的广度优先搜索
void BFS(ALGraph G)
{
int i,vi;
char ch;
VNode *ptr;
LinkQueue q;
for(vi=1;vi<=G.length;vi++)
visited[vi]=FALSE;
puts("输入开始遍历节点");
next:
ch=getche();
printf("\n");
for(i=1;i<=G.length;i++)
if(G.adjlist[i]->ch==ch)
break;
if(i>G.length)
{
puts("错误,重新输入遍历节点值");
goto next;
}
InitQueue(&q); //构造队列
EnQueue(&q,i);
while(!QueueEmpty(q))
{
DeQueue(&q,&vi);
if(!visited[vi])
{
printf("%c ",G.adjlist[vi]->ch);
visited[vi]=TRUE;
ptr=G.adjlist[vi]->link;
while(ptr)
{
EnQueue(&q,ptr->vertex);
ptr=ptr->link;
}
}
}
}
//搜索表组后节点函数
VNode *searchlast(VNode *linklist)
{
VNode *ptr;
ptr=linklist;
while(ptr->link!=NULL)
ptr=ptr->link;
return ptr;
}
void main()
{
ALGraph v;
char c;
puts("是否读盘(y/n)");
c=getche();
if(c=='y')
ReadAdjList(&v); //以矩阵创建图
else
AdjList(&v); //以邻接表创建图
show_adjlist(v); //显示表的数据
show_matrix(v);
IO_V(v);
printf("\n");
puts("-----深度优先搜索-----");
DFS(v);
puts("-----广度优先搜索-----");
BFS(v);
printf("\n\n");
system("pause");
}