#include <stdio.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE 1
//#define NULL 0
#define Error printf
#define MaxVertexNum 10 /*最大顶点数*/
//#define INFINE 9999
typedef struct node{ /*边结点结构*/
int adjvex; /*与顶点相连的邻接点下标*/
int weight;/*权*/
struct node *next; /*下一个邻接点*/
}EdgeNode;
//typedef int Vertextype;
typedef struct vnode{ /*顶点结构*/
int vertex; /*顶点信息*/
int indegree;//入度
EdgeNode *firstedge; /*指向第一个邻接点的指针*/
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum];//点集
typedef struct{
AdjList adjlist;
int n,e;
}ALGraph;
int visited[MaxVertexNum];/*访问标志域*/
#define QueueSize 30 /*队列大小*/
typedef int DataType;
int haspath=0;
typedef struct{
int front; /*队头指针*/
int rear; /*队尾指针*/
int count; /*队列中数个数*/
DataType data[QueueSize];
}CirQueue;
//CirQueue dui;
typedef struct {
int data[MaxVertexNum];
int top;
}stack;
//void CreateALGraph(ALGraph *G);
//void DFSTraverseAL(ALGraph *G);
//void BFSTraverseAL(ALGraph *G);
//void DFSAL(ALGraph *G,int i);
//void BFSAL(ALGraph *G,int i);
void InitQueue(CirQueue *Q) /*初始化队列*/
{
// Q->data=(DataType *)malloc(MaxVertexNum*sizeof(DataType));
Q->front=Q->rear=0;
Q->count=0;
}
int QueueEmpty(CirQueue *Q) /*判队空*/
{
if (Q->front==Q->rear) return 1;
return 0;
}
int QueueFull(CirQueue *Q) /*判队满*/
{
return Q->count==QueueSize;
}
void EnQueue(CirQueue *Q,DataType x)//入队
{
Q->count++;
Q->data[Q->rear]=x;
Q->rear=(Q->rear+1)%QueueSize;
}
DataType DeQueue(CirQueue *Q) /*出队*/
{
DataType temp;
// printf("%d",Q->rear);
//printf("%d",Q->front);
// printf("%d",QueueEmpty(Q));
if (QueueEmpty(Q)){
printf("队列为空");
return 0;
}
else {
temp=Q->data[Q->front];
Q->count--;
Q->front=(Q->front+1)%QueueSize;
return temp;
}
}
void Initstack(stack *s){//初始化栈
s->top=0;
}
int stackEmpty(stack *s){//判栈空
if(s->top==0)
return 1;
else
return 0;
}
int stackFull(stack *s){
return s->top==MaxVertexNum-1;
}
void push(stack *s,DataType x){
if(!stackFull(s)){
s->data[s->top]=x;
s->top++;
}
else
{
printf("栈满!");
exit(1);
}
}
DataType pop(stack *s){
int temp;
s->top--;
temp=s->data[s->top];
return temp;
}
void DispAdj(ALGraph *G,int r){
int i;
EdgeNode *p;
for(i=1;i<=G->n;i++){
p=G->adjlist[i].firstedge;
printf("V[%d]->",i);
if(p!=NULL)
// printf("V[%d]->",i);
while (p!=NULL){
printf("%d",p->adjvex);
if(r>=3)
printf("(%d)",p->weight);
if(p->next!=NULL)
printf("->");
p=p->next;
}
printf("\n");
}
}
void MenuList()
{
printf("\n\n\n**************************\n");
printf(" 1 ------- 生成图\n");
printf(" 2 ------- 深度优先\n");
printf(" 3 ------- 广度优先\n");
printf(" 4 ------- 拓扑排序\n");
printf(" 5 ------- 简单路径\n");
printf(" 0 ------- 退出\n");
printf("**************************\n");
}
void CreateALGraph(ALGraph *G)
{
int i,j,k,r,w;
EdgeNode *s;
printf("请输入顶点数和边数,输入格式:(vn,en):\n");
scanf("%d,%d",&(G->n),&(G->e));
printf("请输入图的类型,输入格式: (number<CR>):\n");
scanf("%d",&r);
printf("请输入顶点值,输入格式: (number<CR>):\n");
for (i=1;i<=G->n;i++)
{
scanf("\n%d",&(G->adjlist[i].vertex));
G->adjlist[i].firstedge=NULL;
G->adjlist[i].indegree=0;
}
printf("输入边,输入格式:(i,j<CR>):\n");
if (r==1)
{ //无向图
for ( k = 1; k <=G->e; k++) {
printf("输入第%d条边:",k);
scanf("\n%d,%d",&i,&j);
s=(EdgeNode*)malloc(sizeof(EdgeNode));//头插法
s->adjvex=j;
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s;
s=(EdgeNode*)malloc(sizeof(EdgeNode));
s->adjvex=i;
s->next=G->adjlist[j].firstedge;
G->adjlist[j].firstedge=s;
}
}
if (r==2)
{ //有向图
for (k=1;k<=G->e;k++)//头插法
{
printf("输入第%d条边:",k);
scanf("\n%d,%d",&i,&j);
s=(EdgeNode*)malloc(sizeof(EdgeNode));
s->adjvex=j;
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s;
G->adjlist[j].indegree++;
}}
if (r==3) {
for (k = 1; k <= G->e; k++) {
printf("输入第%d条边:\n", k);
scanf("%d,%d", &i, &j);
printf("请输入该边的权值:");
scanf("%d",&w);
s = (EdgeNode *) malloc(sizeof(EdgeNode));
s->adjvex = j;
s->weight = w;
s->next = G->adjlist[i].firstedge;
G->adjlist[i].firstedge = s;
s = (EdgeNode *) malloc(sizeof(EdgeNode));
s->adjvex = i;
s->weight = w;
s->next = G->adjlist[j].firstedge;
G->adjlist[j].firstedge = s;
}
}
if (r==4)
{
for (k = 1; k <= G->e; k++) {
printf("输入第%d条边:\n", k);
scanf("%d,%d", &i, &j);
printf("请输入该边的权值:");
scanf("%d",&w);
s = (EdgeNode *) malloc(sizeof(EdgeNode));
s->adjvex = j;
s->weight=w;
s->next = G->adjlist[i].firstedge;
G->adjlist[i].firstedge = s;
}
}
DispAdj(G,r);
}
void DFSAL(ALGraph *G,int i)
{
EdgeNode *p;
printf("访问顶点:V%d\n",G->adjlist[i].vertex);
visited[i]=1;
p=G->adjlist[i].firstedge;
while(p!=NULL)
{if (!visited[p->adjvex])
DFSAL(G,p->adjvex);
p=p->next;
}
}
void DFSTraverseAL(ALGraph *G)
{
int i,k;
printf("深度优先遍历\n");
for (i=1;i<=G->n;i++){
visited[i]=0;
}
printf("请输入遍历的初始顶点的地址下标:");
scanf("%d",&k);
//printf("%d",k);
DFSAL(G,k);
for (i=1;i<=G->n;i++)
if (!visited[i])
DFSAL(G,i);
}
void BFSAL(ALGraph *G,int i) {
int k;
CirQueue q;
InitQueue(&q);
EdgeNode *p;
printf("访问顶点:V%d\n", G->adjlist[i].vertex);
visited[i] = 1;
EnQueue(&q, i);
while (!QueueEmpty(&q)){
// printf("666666666");
k = DeQueue(&q);
p = G->adjlist[k].firstedge;
while (p) {
if (!visited[p->adjvex]) {
printf("访问顶点:V%d\n", p->adjvex);
visited[p->adjvex] = 1;
EnQueue(&q, p->adjvex);
}
p = p->next;
}
// printf("hhhhhhhhhhhhhhhh");
}
}
void BFSTraverseAL(ALGraph *G)//输出
{
int i,k;
printf("广度优先遍历\n");
for (i=1;i<=G->n;i++)
visited[i]=0;
printf("请输入遍历的初始顶点的地址下标:");
scanf("%d",&k);
BFSAL(G,k);
for (i=1;i<=G->n;i++)
if (!visited[i]) BFSAL(G,i);
}
void TSequence(ALGraph *G){
stack s;
Initstack(&s);
EdgeNode *p;
int i,j,k,m=0;
int t[MaxVertexNum];
for ( i = 1; i <=G->n ; i++)
visited[i]=0;
for (i = 1; i <=G->n ; i++) {
if(G->adjlist[i].indegree==0)
push(&s,i);
}
while (!stackEmpty(&s)){
k=pop(&s);
visited[k]=1;
m++;
t[m]=k;
p=G->adjlist[k].firstedge;
while (p) {
G->adjlist[p->adjvex].indegree--;
if (G->adjlist[p->adjvex].indegree == 0)
push(&s, p->adjvex);
p = p->next;
}
}
if(m==G->n){
printf("拓扑排序成功\n");
printf("拓扑排序为:");
for (i = 1; i <=m ; i++) {
j=t[i];
printf("V%d ",G->adjlist[j].vertex);
}
printf("\n");
}
else{
printf("拓扑排序失败,AOV网中存在环!\n");
printf("拓扑排序中的顶点只有:");
for (i = 1; i <=m ; i++) {
j=t[i];
printf("V%d ",G->adjlist[j].vertex);
}
printf("\n");
}
}
int LocateVex(ALGraph *G,int v){//根据结点值找到下标
int i;
for(i=0;i<=G->n;i++)
if(G->adjlist[i].vertex==v)
return i;
}
int existPath(int a,int b,ALGraph *G){//利用深度优先遍历
int m,n;
m=LocateVex(G,a);
n=LocateVex(G,b);
visited[m]=1;
EdgeNode *p;
p = G->adjlist[m].firstedge;
//printf("p :%d\n",p->adjvex);
if(m == n) {
haspath=1;
}
while(p){
if(p->adjvex == n) { // 如果p的出边等于b意味着找到了
haspath= 1;
break;
}
if(!visited[p->adjvex]) // p的出边没有被访问
existPath(G->adjlist[p->adjvex].vertex,b,G); // 递归调用
p=p->next;
}
}
void print_Path(int d,int z,ALGraph *G){//输出两点连接路径
int m,n;
m=LocateVex(G,d);
n=LocateVex(G,z);
EdgeNode *p = G->adjlist[m].firstedge;
printf("\n路径为:V%d",d);
while(p){
printf("->V%d",p->adjvex);
if(p->adjvex == n)break;
p = G->adjlist[p->adjvex].firstedge;
}printf("\n");}
//int print_Path(int d,int z,ALGraph *G){//输出两点连接路径
// int m,n;
// m=LocateVex(G,d);
// n=LocateVex(G,z);
// EdgeNode *p = G->adjlist[m].firstedge;
// if(m == n)
// printf("V%d->V%d",m,n);
// while(p){
// if(!visited[p->adjvex]){ // p的出边没有被访问
// printf("->V%d",p->adjvex);
// if(p->adjvex == n)// 如果p的出边等于b意味着找到了
// break;
// print_Path(G->adjlist[p->adjvex].vertex,z,G);// 递归调用
// }
// p=p->next;
// }
//}
int main()
{
ALGraph* G; /*定义一个图变量*/
int o=100;
int a,b,i;
CirQueue s;
MenuList();
G=(ALGraph*) malloc (sizeof(ALGraph) );
G->n =0;
G->e =0;
while(o!=0)
{ printf("请选择操作:");
scanf("%d",&o);
if (o==1)
CreateALGraph(G);
if(o==2)
DFSTraverseAL(G);
if(o==3)
BFSTraverseAL(G);
if(o==4)
TSequence(G);
if(o==5){
printf("判断a,b 之间是否存在路径:");
scanf("%d,%d",&a,&b);
for ( i = 1; i <=G->n ; i++)
visited[i]=0;
existPath(a,b,G);
if(haspath==1){
// for ( i = 1; i <=G->n ; i++)
// visited[i]=0;
printf("存在\n");
// printf("路径为:V%d",a);
print_Path(a,b,G);
}else{
printf("不存在");
}
}
// if(o==6){
// InitQueue(&s);
// scanf("%d",&a);
// EnQueue(&s,a);
// b=QueueEmpty(&s);
// printf("%d\n",b);
// i= DeQueue(&s);
// printf("%d\n",i);
// }
}
}
代码-图(邻接表)
于 2022-08-15 19:13:15 首次发布