邻接表存储的图的基本操作c++

来源:互联网 发布:linux 安装squid 编辑:程序博客网 时间:2024/06/05 09:25

注:若有错误或需要改进的地方,或有需要补充的内容请告之,新手上路,谢谢。有些函数还是比较冗余的,慢慢改进。

头文件:

/*使用栈和队列要用指针*//************结构体************//*队列*/typedef struct qnode{    void* data;    struct qnode *next;}qnode;typedef struct{    qnode *front_,*rear;}linkqueue;/*栈*/typedef struct node{    void* data;    struct node *next;}stacknode,*pstacknode;typedef struct linkstac{    stacknode *base;    stacknode *top;}linkstack,*plinkstack;/*************队列操作************//*队列初始化*/linkqueue *init_queue(){    linkqueue *q;    q=(linkqueue*)malloc((sizeof(linkqueue)));    q->front_=(qnode*)malloc(sizeof(qnode));    q->front_->next=NULL;                   //带对头结点    q->rear=q->front_;    return q;}/*判断队空*/bool isempty_queue(linkqueue q){    if(q.front_==q.rear)    {        return true;    }    else    {        return false;    }}/*入队*/void enqueue(linkqueue *q,void* e){    qnode *s;    s=(qnode*)malloc(sizeof(qnode));    s->data=e;    s->next=NULL;    q->rear->next=s;    q->rear=s;}/*出队*/void dequeue(linkqueue *q,void* e){    if(q->front_==q->rear)    {        printf("队空");    }    else    {        qnode *s;        s=(qnode*)malloc(sizeof(qnode));        s=q->front_->next;        e=s->data;        q->front_->next=s->next;        if(q->rear==s)  //只有一个元素        {            q->rear=q->front_;        }        free(s);    }}/*******************栈的操作********************//*链式栈初始化*/linkstack *init_stack(){    linkstack *s;    s=(linkstack*)malloc(sizeof(linkstack));    s->base=(stacknode*)malloc(sizeof(stacknode));    s->top=s->base;    s->base->next=NULL;    return s;}/*判断链式栈空*/bool isempty_stack(linkstack *s){    if(s->base==s->top)    {        return true;    }    else    {        return false;    }}/*入栈*/void push(linkstack *s,void* e){    stacknode *p;    p=(stacknode*)malloc(sizeof(stacknode));    p->data=e;    p->next=s->top;    s->top=p;}/*出栈*/void pop(linkstack *s,void* &e){    if(s->top==s->base)    {        printf("栈空");    }    else    {        stacknode *p=s->top;        e=p->data;        s->top=p->next;        free(p);    }}/*链式栈的长度*/int length(linkstack *s){    stacknode *p=s->top;    int i=0;    while(p!=s->base)    {        i++;        p=p->next;    }    return i;}/*返回栈顶元素*/void stack_get_top(linkstack *s,void* e){    if(s->base==s->top)    {        printf("栈空");    }    else    {        e=s->top->data;    }}
图的代码:

#include<stdio.h>#include<stdlib.h>#include<string>#include<cstring>#include<math.h>#include<algorithm>#include<ctype.h>#include"../../头文件/link_stack_queue.h"using namespace std;#define MAXSIZE 100bool visited[MAXSIZE];typedef enum{    NN,    NY,    YN,    YY}AlGraph_type;/*******************结构体*********************//*邻接表*/typedef struct ArcNode  //边表结点{    int adjvex; //弧头结点的编号    struct ArcNode *nextarc;    int info;   //有权图为边权值,无权图为0}ArcNode;typedef struct    //顶点表结点{    char data;  //结点值    ArcNode *firstarc;  //该顶点的第一条弧}VNode,AdjList[MAXSIZE];typedef struct{    AdjList vextable;    int vexnum,arcnum;    int AlGraph_type;}AlGraph;/*******************对图操作的预先函数*********************//*判断结点是否在图中*/bool if_vex_in(AlGraph a,char e){    int i;    for(i=0;i<a.vexnum;i++)    {        if(a.vextable[i].data==e)        {            return true;        }    }    return false;}/*返回结点在顶点表中的编号*/int return_vex(AlGraph a,char e){    int i;    for(i=0;i<a.vexnum;i++)    {        if(a.vextable[i].data==e)        {            return i;        }    }    return -1;}/*返回某一结点的出度*/int return_vex_outnum(AlGraph a,char e){    int i=0,n;    if(!if_vex_in(a,e))    {        printf("该结点不在图中\n");        return -1;    }    n=return_vex(a,e);    ArcNode *r=a.vextable[n].firstarc;    while(r!=NULL)    {        r=r->nextarc;        i++;    }    return i;}/*输出图*/void print_AlGraph(AlGraph a){    int i,n,j;    ArcNode *p;    printf("该图的邻接表为:\n");    printf("  顶点表     边结点(ajdvex,info)\n");    for(i=0;i<a.vexnum;i++)    {        printf(" %d | %c |-->",i,a.vextable[i].data);        n=return_vex_outnum(a,a.vextable[i].data);        p=a.vextable[i].firstarc;        for(j=0;j<n;j++)        {            printf("| %d |",p->adjvex);            if(a.AlGraph_type==2||a.AlGraph_type==4)            {                printf(" %d |",p->info);            }            printf("-->");            p=p->nextarc;        }        printf("NULL\n");    }    printf("图的结点数为%d,边数为%d\n",a.vexnum,a.arcnum);}/*初始化图*/AlGraph *init_AlGraph(){    AlGraph *a;    int i;    a=(AlGraph*)malloc(sizeof(AlGraph));    a->arcnum=a->vexnum=0;    printf("请选择图的类型 1、无向图 2、无向网 3、有向图 4、有向网:");    fflush(stdin);    scanf("%d",&i);    a->AlGraph_type=i;    fflush(stdin);    memset(a->vextable,'#',sizeof(a->vextable)); //初始顶点表由#填充    for(i=0;i<MAXSIZE;i++)    {        a->vextable[i].firstarc=(ArcNode*)malloc(sizeof(ArcNode));        a->vextable[i].firstarc=NULL;    }    return a;}/*判断创建的边是否已存在*/bool if_arc_in(AlGraph a,int xn,int yn)   //xn,yn为头尾结点的编号{    int i;    ArcNode *r;    for(i=0,r=a.vextable[xn].firstarc;i<return_vex_outnum(a,a.vextable[xn].data);r=r->nextarc,i++)    {        if(r->adjvex==yn)        {            return true;        }    }    return false;}/*******************无向图*********************//*构建图*/void create_AlGraph_NN(AlGraph *a){    int V,E,i,xn,yn;    char x,y;    ArcNode *p1,*p2;    printf("构建无向图\n请输入结点数与边数:");    scanf("%d %d",&V,&E);    printf("请输入头尾结点:\n");    for(i=0;i<E;i++)    {        fflush(stdin);        scanf("%c %c",&x,&y);        fflush(stdin);        if(!if_vex_in(*a,x))        {            (a->vextable[a->vexnum++].data)=x;        }        if(!if_vex_in(*a,y))        {            (a->vextable[a->vexnum++].data)=y;        }        xn=return_vex(*a,x);        yn=return_vex(*a,y);        if(if_arc_in(*a,xn,yn)||if_arc_in(*a,yn,xn))        {            continue;        }        p1=(ArcNode*)malloc(sizeof(ArcNode));        p1->info=0;        p1->adjvex=yn;        p1->nextarc=a->vextable[xn].firstarc;        a->vextable[xn].firstarc=p1;        p2=(ArcNode*)malloc(sizeof(ArcNode));        p2->info=0;        p2->adjvex=xn;        p2->nextarc=a->vextable[yn].firstarc;        a->vextable[yn].firstarc=p2;        a->arcnum++;    }}/*******************有向图*********************//*构建图*/void create_AlGraph_YN(AlGraph *a){    int V,E,i,xn,yn;    char x,y;    ArcNode *p1;    printf("构建有向图\n请输入结点数与边数:");    scanf("%d %d",&V,&E);    printf("请输入头尾结点:\n");    for(i=0;i<E;i++)    {        fflush(stdin);        scanf("%c %c",&x,&y);        fflush(stdin);        if(!if_vex_in(*a,x))        {            (a->vextable[a->vexnum++].data)=x;        }        if(!if_vex_in(*a,y))        {            (a->vextable[a->vexnum++].data)=y;        }        xn=return_vex(*a,x);        yn=return_vex(*a,y);        if(if_arc_in(*a,xn,yn))        {            continue;        }        p1=(ArcNode*)malloc(sizeof(ArcNode));        p1->adjvex=yn;        p1->info=0;        p1->nextarc=a->vextable[xn].firstarc;        a->vextable[xn].firstarc=p1;        a->arcnum++;    }}/*******************无向网*********************//*构建图*/void create_AlGraph_NY(AlGraph *a){    int V,E,i,c,xn,yn;    char x,y;    ArcNode *p1,*p2;    printf("构建无向网\n请输入结点数与边数:");    scanf("%d %d",&V,&E);    printf("请输入头尾结点与权值:\n");    for(i=0;i<E;i++)    {        fflush(stdin);        scanf("%c %c %d",&x,&y,&c);        fflush(stdin);        if(!if_vex_in(*a,x))        {            (a->vextable[a->vexnum++].data)=x;        }        if(!if_vex_in(*a,y))        {            (a->vextable[a->vexnum++].data)=y;        }        xn=return_vex(*a,x);        yn=return_vex(*a,y);        if(if_arc_in(*a,xn,yn)||if_arc_in(*a,yn,xn))        {            continue;        }        p1=(ArcNode*)malloc(sizeof(ArcNode));        p1->info=c;        p1->adjvex=yn;        p1->nextarc=a->vextable[xn].firstarc;        a->vextable[xn].firstarc=p1;        p2=(ArcNode*)malloc(sizeof(ArcNode));        p2->info=c;        p2->adjvex=xn;        p2->nextarc=a->vextable[yn].firstarc;        a->vextable[yn].firstarc=p2;        a->arcnum++;    }}/*******************有向网*********************//*构建图*/void create_AlGraph_YY(AlGraph *a){    int V,E,i,xn,yn,c;    char x,y;    ArcNode *p1;    printf("构建有向网\n请输入结点数与边数:");    scanf("%d %d",&V,&E);    printf("请输入头尾结点与权值:\n");    for(i=0;i<E;i++)    {        fflush(stdin);        scanf("%c %c %d",&x,&y,&c);        fflush(stdin);        if(!if_vex_in(*a,x))        {            (a->vextable[a->vexnum++].data)=x;        }        if(!if_vex_in(*a,y))        {            (a->vextable[a->vexnum++].data)=y;        }        xn=return_vex(*a,x);        yn=return_vex(*a,y);        if(if_arc_in(*a,xn,yn))        {            continue;        }        p1=(ArcNode*)malloc(sizeof(ArcNode));        p1->adjvex=yn;        p1->info=c;        p1->nextarc=a->vextable[xn].firstarc;        a->vextable[xn].firstarc=p1;        a->arcnum++;    }}/*******************对图操作*********************//*创建图*/AlGraph *create_AlGraph(){    AlGraph *a;    a=init_AlGraph();    switch (a->AlGraph_type)    {        case 1:create_AlGraph_NN(a);break;        case 2:create_AlGraph_NY(a);break;        case 3:create_AlGraph_YN(a);break;        case 4:create_AlGraph_YY(a);break;    }    return a;}/*初始化visited[]*/void init_visited(AlGraph a){    int i;    for(i=0;i<a.vexnum;i++)    {        visited[i]=false;   //false为未访问    }    for(i=a.vexnum;i<MAXSIZE;i++)    {        visited[i]=true;    }}/*深度优先遍历*/void DFS(AlGraph a,int n)   //n为结点的编号{    int i;    ArcNode *r;    printf("%c",a.vextable[n].data);    visited[n]=true;    for(r=a.vextable[n].firstarc,i=0;i<return_vex_outnum(a,a.vextable[n].data);i++,r=r->nextarc)    {        if(!visited[r->adjvex])        {            DFS(a,r->adjvex);        }    }}void DFSTraverse(AlGraph a){    printf("该图的深度优先遍历为:");    int i;    init_visited(a);    for(i=0;i<a.vexnum;i++)    {        if(!visited[i])        {            DFS(a,i);        }    }    printf("\n");}/*广度优先遍历*/void BFS(AlGraph a,int *n)   //n为结点的编号{    int i;    ArcNode *r;    linkqueue *q;    q=init_queue();    printf("%c",a.vextable[*n].data);    visited[*n]=true;    enqueue(q,n);    while(!isempty_queue(*q))    {        dequeue(q,n);        for(r=a.vextable[*n].firstarc,i=0;i<return_vex_outnum(a,a.vextable[*n].data);r=r->nextarc,i++)        {            if(!visited[r->adjvex])            {                printf("%c",a.vextable[r->adjvex].data);                visited[r->adjvex]=true;                enqueue(q,&(r->adjvex));            }        }    }}void BFSTraverse(AlGraph a){    printf("该图的广度优先遍历为:");    int i;    init_visited(a);    for(i=0;i<a.vexnum;i++)    {        if(!visited[i])        {            BFS(a,&i);        }    }    printf("\n");}/*插入一条弧*/void insert_arc(AlGraph *a,char x,char y,int c){    if(!if_vex_in(*a,x)||!if_vex_in(*a,y))    {        printf("插入的弧的结点不存在\n");        return ;    }    int xn,yn;    xn=return_vex(*a,x);    yn=return_vex(*a,y);    if(a->AlGraph_type==1||a->AlGraph_type==2)  //NN NY    {        if(if_arc_in(*a,xn,yn)||if_arc_in(*a,yn,xn))        {            printf("要插入的弧已存在\n");            return ;        }        if(a->AlGraph_type==1)  //NN        {            ArcNode *r1;            r1=(ArcNode*)malloc(sizeof(ArcNode));            r1->adjvex=yn;            r1->nextarc=a->vextable[xn].firstarc;            a->vextable[xn].firstarc=r1;            ArcNode *r2;            r2=(ArcNode*)malloc(sizeof(ArcNode));            r2->adjvex=xn;            r2->nextarc=a->vextable[yn].firstarc;            a->vextable[yn].firstarc=r2;            a->arcnum++;        }        else        {            ArcNode *r1;            r1=(ArcNode*)malloc(sizeof(ArcNode));            r1->adjvex=yn;            r1->info=c;            r1->nextarc=a->vextable[xn].firstarc;            a->vextable[xn].firstarc=r1;            ArcNode *r2;            r2=(ArcNode*)malloc(sizeof(ArcNode));            r2->adjvex=xn;            r2->info=c;            r2->nextarc=a->vextable[yn].firstarc;            a->vextable[yn].firstarc=r2;            a->arcnum++;        }    }    else    {        if(if_arc_in(*a,xn,yn))        {            printf("要插入的结点已存在\n");            return ;        }        if(a->AlGraph_type==3)  //YN        {            ArcNode *r;            r=(ArcNode*)malloc(sizeof(ArcNode));            r->adjvex=yn;            r->nextarc=a->vextable[xn].firstarc;            a->vextable[xn].firstarc=r;            a->arcnum++;        }        else        {            ArcNode *r;            r=(ArcNode*)malloc(sizeof(ArcNode));            r->adjvex=yn;            r->info=c;            r->nextarc=a->vextable[xn].firstarc;            a->vextable[xn].firstarc=r;            a->arcnum++;        }    }}/*删除一条弧*/bool delete_arc(AlGraph *a,char x,char y){    int xn=return_vex(*a,x),yn=return_vex(*a,y),i;    if(!if_arc_in(*a,xn,yn))    {        printf("要删除的弧不存在\n");        return false;    }    ArcNode *r;    if(a->AlGraph_type==1||a->AlGraph_type==2)  //NN NY    {       for(r=a->vextable[xn].firstarc,i=0;i<return_vex_outnum(*a,x);r=r->nextarc,i++)       {           if(i==0)           {               if(r->adjvex==yn)               {                   a->vextable[xn].firstarc=r->nextarc;                   a->arcnum--;                   break;               }           }           if(r->nextarc->adjvex==yn)           {               ArcNode *p=r->nextarc;               r->nextarc=p->nextarc;               free(p);               a->arcnum--;               break;           }       }       for(r=a->vextable[yn].firstarc,i=0;i<return_vex_outnum(*a,y);r=r->nextarc,i++)       {           if(i==0)           {               if(r->adjvex==xn)               {                   a->vextable[yn].firstarc=r->nextarc;                   a->arcnum--;                   return true;               }           }           if(r->nextarc->adjvex==xn)           {               ArcNode *p=r->nextarc;               r->nextarc=p->nextarc;               free(p);               a->arcnum--;               return true;           }       }    }    else    {        for(r=a->vextable[xn].firstarc,i=0;i<return_vex_outnum(*a,x);r=r->nextarc,i++)       {           if(i==0)           {               if(r->adjvex==yn)               {                   a->vextable[xn].firstarc=r->nextarc;                   a->arcnum--;                   return true;               }           }           if(r->nextarc->adjvex==yn)           {               ArcNode *p=r->nextarc;               r->nextarc=p->nextarc;               free(p);               a->arcnum--;               return true;           }       }    }}/*插入一个结点*/void insert_node(AlGraph *a){    printf("请输入要插入的结点:");    char x;    fflush(stdin);    scanf("%c",&x);    if(if_vex_in(*a,x))    {        printf("插入的结点已存在\n");        return ;    }    a->vextable[a->vexnum++].data=x;    //a->vextable[a->vexnum-1].firstarc=NULL; 已在初始化时全部设置为NULL}/*删除一个结点*/bool delete_node(AlGraph *a){    printf("输入要删除的结点:");    char x;    fflush(stdin);    scanf("%c",&x);    if(!if_vex_in(*a,x))    {        printf("要删除的结点不存在\n");        return false;    }    int xn,i,j,num=0;    xn=return_vex(*a,x);    ArcNode *r;    for(i=0;i<a->vexnum;i++)    //删除边    {        if(i==xn)        {            continue;        }        for(r=a->vextable[i].firstarc,j=0;j<return_vex_outnum(*a,a->vextable[i].data);r=r->nextarc,j++)        {            if(r->adjvex==xn)            {                delete_arc(a,a->vextable[i].data,x);                num++;            }        }    }    if(a->AlGraph_type==1||a->AlGraph_type==2)    {        a->arcnum+=num;    }    else    {        a->arcnum-=return_vex_outnum(*a,a->vextable[xn].data);    }    for(i=0;i<a->vexnum;i++)    {        if(i>=xn)        {            a->vextable[i].data=a->vextable[i+1].data;            a->vextable[i].firstarc=a->vextable[i+1].firstarc;        }            for(r=a->vextable[i].firstarc,j=0;j<return_vex_outnum(*a,a->vextable[i].data);r=r->nextarc,j++)            {                if(r->adjvex>xn)                {                    r->adjvex--;                }            }    }    a->vexnum--;}int main(){    AlGraph *a;    a=create_AlGraph();    print_AlGraph(*a);    fflush(stdin);    delete_node(a);    print_AlGraph(*a);    BFSTraverse(*a);    DFSTraverse(*a);    return 0;}/*a c 3a d 8a b 5c d 10d a 7d b 20a ca da bc dd ad b*/



0 0
原创粉丝点击