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

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

头文件:



/*使用栈和队列要用指针*/


/************结构体************/
/*队列*/
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 100

bool 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 3
a d 8
a b 5
c d 10
d a 7
d b 20
a c
a d
a b
c d
d a
d b
*/



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值