代码-图(邻接表)

#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);
//                }
                }
            }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的锦鲤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值