图的基本操作(邻接表)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

图的基本操作如下:
基本操作:void CreatGraph(AlGraph &G, VextexType Vlist[], int VlistLength, int arclist[][2], int arcLength,int kind);//图、顶点信息、顶点个数、弧信息、弧个数。
/* 注:VextexType Vlist[]为顶点的集合
arclist[][2]为边或弧的信息集合,当图为无向图时,只需给出边的信息即可,不强调方向性,例如(0,1)与(1,0)是相同的
当其为有向图时强调方向性,例如<0,1><1,0>不同
*/
bool Adjacent(AlGraph G, int x, int y); //判断图G是否存在边<x,y>
void Neighbors(AlGraph G, VextexType x); //列出图G中与节点x相邻接的边
bool InsertVertex(AlGraph &G, VextexType x, int arclist[][2],int arclength); //在图G中插入顶点x
void DeletetVertex(AlGraph &G, VextexType x); //在图G中插入删除x
void AddEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边
void RemoveEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>存在,则向图G中删除该边
int FirstNeighbor(AlGraph G, VextexType x); //求图G中顶点x第一个邻接点,若有则返回顶点号,若x没有邻接点或图G不存在,返回-1
int Get_edge_value(AlGraph G, int x, int y); //获取图G中边(x,y)或弧<x,y>对应的权值
void Set_edge_value(AlGraph &G, int x, int y, int v); //设置图G中边(x,y)或弧<x,y>对应的权值


一、图的基本操作(邻接表)

1.头文件

代码如下(示例):

#ifndef GRAPH_H
#define GRAPH_H
#define MaxVertexNum 10
typedef char VextexType; //顶点类型
/*顶点:vertex,边:edge,弧:arc*/

typedef struct ArcNode //弧/边
{
    int Adjvex;           //边/弧指向哪个节点
    struct ArcNode *next; //指向下一条弧的指针
    int info;//边权值
} ArcNode;

typedef struct VNode //顶点
{
    VextexType data; //顶点信息
    ArcNode *first;  //第一条边/弧
} VNode, AdjList[MaxVertexNum];

typedef struct //图
{
    AdjList vertices;   //节点数组
    int vexnum, arcnum; //顶点数和边数
    int kind;           //图类型:0为无向图,1为有向图
} AlGraph;
void CreatGraph(AlGraph &G, VextexType Vlist[], int VlistLength, int arclist[][2], int arcLength,int kind);//图、顶点信息、顶点个数、弧信息、弧个数。
/*  注:VextexType Vlist[]为顶点的集合
    arclist[][2]为边或弧的信息集合,当图为无向图时,只需给出边的信息即可,不强调方向性,例如(0,1)与(1,0)是相同的
    当其为有向图时强调方向性,例如<0,1><1,0>不同
*/
bool Adjacent(AlGraph G, int x, int y); //判断图G是否存在边<x,y>
void Neighbors(AlGraph G, VextexType x); //列出图G中与节点x相邻接的边
bool InsertVertex(AlGraph &G, VextexType x, int arclist[][2],int arclength); //在图G中插入顶点x
void DeletetVertex(AlGraph &G, VextexType x); //在图G中插入删除x
void AddEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边
void RemoveEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>存在,则向图G中删除该边
int FirstNeighbor(AlGraph G, VextexType x); //求图G中顶点x第一个邻接点,若有则返回顶点号,若x没有邻接点或图G不存在,返回-1
int Get_edge_value(AlGraph G, int x, int y); //获取图G中边(x,y)或弧<x,y>对应的权值
void Set_edge_value(AlGraph &G, int x, int y, int v); //设置图G中边(x,y)或弧<x,y>对应的权值
#endif // GRAPH_H

2.Graph

代码如下(示例):

#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"
void CreatGraph(AlGraph &G, VextexType Vlist[], int VlistLength, int arclist[][2], int arcLength, int kind) //图、顶点信息、顶点个数、弧信息、弧个数。
{
    for (int index = 0; index < VlistLength; index++)
    {
        G.vertices[index].data = Vlist[index];
        G.vertices[index].first = NULL;
    }
    for (; VlistLength <= MaxVertexNum; VlistLength++)
    {
        G.vertices[VlistLength].data = '\0';
        G.vertices[VlistLength].first = NULL;
    }
    for (int i = 0; i < arcLength; i++)
    {
        int v = arclist[i][0]; //边(弧)<v,w>依附的v
        int w = arclist[i][1]; //边(弧)<v,w>依附的w
        ArcNode *parcnode = (ArcNode *)malloc(sizeof(ArcNode));
        parcnode->Adjvex = w;
        parcnode->next = G.vertices[v].first;
        G.vertices[v].first = parcnode; //头插法
    }
    G.arcnum = arcLength;
    G.vexnum = VlistLength;
    G.kind = kind; //G.kind=1(0为无向图,1为有向图)
}
bool Adjacent(AlGraph G, int x, int y) //判断图G是否存在边<x,y>
{
    ArcNode *p = G.vertices[x].first;
    for (; p != NULL; p = p->next)
    {
        if (p->Adjvex == y)
            return true;
    }
    return false;
}
void Neighbors(AlGraph G, VextexType x) //列出图G中与节点x相邻接的边
{
    int n = -1;
    for (int i = 0; G.vertices[i].data != '\0'; i++) //找出节点x所在的那一行
    {
        if (G.vertices[i].data == x)
            n = i;
    }
    if (n != -1)
    {
        if (G.kind == 0) //G为无向图
        {
            ArcNode *p = G.vertices[n].first;
            for (; p != NULL; p = p->next)
            {
                printf("%c", G.vertices[p->Adjvex].data);
            }
        }
        if (G.kind == 1) //G为有向图
        {
            ArcNode *p = G.vertices[n].first;
            for (; p->next != NULL; p = p->next)
            {
                printf("%c", G.vertices[p->Adjvex].data);
            }
            for (int i = 0; G.vertices[i].data != '\0'; i++)
            {
                p = G.vertices[i].first;
                for (; p->next != NULL; p = p->next)
                {
                    if (p->Adjvex == n)
                        printf("%c", G.vertices[i].data);
                }
            }
        }
    }
    else
        printf("图中没有此节点\n");
}
bool InsertVertex(AlGraph &G, VextexType x, int arclist[][2], int arclength) //在图G中插入顶点x,
{
    int i = 0, sign;
    for (i = 0; G.vertices[i].data != '\0'; i++) //找出节点x所在的那一行
    {
        if (G.vertices[i].data == x)
            return false;
    }
    G.vertices[i].data = x;
    for (int m = 0; m < arclength; m++)
    {
        int v = arclist[m][0]; //找到需要插入的点
        int w = arclist[m][1];
        if (v != i && w != i)
            return false; //弧信息不包括新加入的节点
        if (v == i && w == i)
            return false; //弧信息不包括其他节点(指向自己)
        ArcNode *p = (ArcNode *)malloc(sizeof(ArcNode));
        p->Adjvex = w;
        p->next = G.vertices[v].first; //头插法插入元素
        G.vertices[v].first = p;
    }
    return true;
}
void DeletetVertex(AlGraph &G, VextexType x) //在图G中删除x
{

    int sign;
    for (int i = 0; G.vertices[i].data != '\0'; i++)
    {
        if (G.vertices[i].data == x)
        {
            sign = i;
            break;
        }
    }
    for (int i = 0; G.vertices[i].data != '\0'; i++)
    {
        ArcNode *p = G.vertices[i].first;
        for (; p != NULL; p = p->next) //删除其他节点的边
        {
            if (p->Adjvex == sign)
            {
                if (p->next == NULL)
                {
                    free(p);
                    break;
                }
                if (p->next != NULL)
                {
                    p->Adjvex = p->next->Adjvex;
                    ArcNode *q = p->next;
                    p->next = q->next;
                    free(q);
                    break;
                }
            }
        }
    }
    ArcNode *t = G.vertices[sign].first;
    for (; t != NULL;)
    {
        ArcNode *m = t;
        t = t->next;
        G.vertices[sign].first = t;
        free(m); //删除操作
    }
    G.vertices[sign].data = '\0';
    //删除操作
}
void AddEdge(AlGraph &G, int x, int y) //若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边
{
    ArcNode *p = G.vertices[x].first;
    bool sign = false;
    while (p->next != NULL) //遍历寻找y,p指针停留在最后一个节点
    {
        if (p->Adjvex == y)
        {
            sign = true;
        }
        p = p->next;
    }
    if (p->Adjvex == y) //最后一个节点上面没有遍历到,重新检查一遍这么设计时间复杂度低
        sign = true;
    if (!sign) //如果没有 插入边
    {
        ArcNode *q = (ArcNode *)malloc(sizeof(ArcNode));
        q->Adjvex = y;
        p->next = q;
    }
}
void RemoveEdge(AlGraph &G, int x, int y) //若无向边(x,y)或有向边<x,y>存在,则向图G中删除该边
{
    ArcNode *p = G.vertices[x].first;
    bool sign = false;
    while (p->next != NULL) //遍历寻找y,p指针停留在找到的边上
    {
        if (p->Adjvex == y)
        {
            sign = true;
            break;
        }
        p = p->next;
    }
    if (p->Adjvex == y) //最后一个节点上面没有遍历到,重新检查一遍这么设计时间复杂度低
        sign = true;
    if (sign) //如果有 删除边(偷天换日法)
    {
        if (p->next == NULL)
            free(p);
        ArcNode *t = p->next;
        p->Adjvex = t->Adjvex;
        p->next = t->next;
        free(t);
    }
}
int FirstNeighbor(AlGraph G, VextexType x) //求图G中顶点x第一个邻接点,若有则返回顶点号,若x没有邻接点或图G不存在,返回-1
{
    int sign;
    for (int i = 0; G.vertices[i].data != '\0'; i++)
    {
        if (G.vertices[i].data == x)
        {
            sign = i;
            break;
        }
    }
    ArcNode *p = G.vertices[sign].first;
    if(p!=NULL) return p->Adjvex;
    else return-1;
}
int Get_edge_value(AlGraph G, int x, int y) //获取图G中边(x,y)或弧<x,y>对应的权值
{   
    ArcNode *p=G.vertices[x].first;
    for(;p!=NULL;p=p->next)
    {
        if(p->Adjvex==y) return p->info;
    }
    return 0;
}
void Set_edge_value(AlGraph &G, int x, int y, int v) //设置图G中边(x,y)或弧<x,y>对应的权值
{
    ArcNode *p=G.vertices[x].first;
    for(;p!=NULL;p=p->next)
    {
        if(p->Adjvex==y) p->info=v;
    }
}

3.main函数

#include <stdio.h>
#include <stdlib.h>
#include"Graph.h"
#include"Graph.cpp"
int main()
{
    AlGraph Graph;
    VextexType Vlist[]={'A','B','C','D','E','F'};
    int VlistLength=6;
    int arcLength=14;//边或弧的个数,对应的是二维数组的个数!!
    int arclist1[][2]={
        {0,1},{0,2},{0,3},
        {1,0},{1,4},{1,5},
        {2,0},{2,4},
        {3,0},{3,5},
        {4,1},{4,2},
        {5,1},{5,3}
    };
    int arclist2[][2]={{6,1},{1,6}};
    CreatGraph(Graph,Vlist,VlistLength,arclist1,arcLength,0);//创建一个无向图

总结

总结:注释写的很详细啊,欢迎大家在评论区留下意见。

  • 8
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
基于邻接表,我们可以对进行以下基本操作: 1. 添加节点:在邻接表中添加一个新的节点,需要把数组的长度增加1,并在数组中添加一个新的元素,表示新的节点。同时,需要把新节点的邻居链表初始化为空。 2. 添加边:在邻接表中添加一条边,需要更新起点和终点的邻居链表。具体来说,我们创建一个新的节点,把它插入起点的邻居链表头部,然后再创建一个节点,把它插入终点的邻居链表头部。 3. 删除节点:在邻接表中删除一个节点,需要把数组中对应的元素删除,并把所有指向该节点的边都删除。 4. 删除边:在邻接表中删除一条边,需要在起点的邻居链表中找到终点,并把终点从链表中删除。同时,需要在终点的邻居链表中找到起点,并把起点从链表中删除。 5. 搜索节点:在邻接表中搜索一个节点,可以直接访问数组中对应的元素。 6. 搜索路径:在邻接表中搜索两个节点之间的路径,可以使用广度优先搜索或深度优先搜索算法。具体来说,我们可以先对起点进行标记,然后从起点开始进行遍历,直到遍历到终点为止。在遍历的过程中,我们需要记录每个节点的前驱节点,以便在找到终点后,可以通过前驱节点逆向构造出起点到终点的路径。 7. 计算最短路径:在邻接表中计算两个节点之间的最短路径,可以使用 Dijkstra 算法或 Bellman-Ford 算法。这些算法都是基于的权重和邻接表进行设计的,具体实现细节可以参考相关文献。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值