数据结构复习代码——图的邻接表的基本操作的实现

1、图的邻接矩阵的基本操作的实现

#include<stdio.h>
#include<malloc.h>
#include<assert.h>

#define Default_Vertex_Size 10

#define T char

//图的定义
typedef struct GraphMtx
{
    int MaxVertices;
    int NumVertices;
    int NumEdges;

    T *VerticesList;
    int **Edge;
}GraphMtx;

void InitGraphMtx(GraphMtx *g);
void InsertVertex(GraphMtx *g,T v);
void ShowGraphMtx(GraphMtx *g);
void InsertEdge(GraphMtx *g,T v1,T v2);
int GetVertexPos(GraphMtx *g,T v);
void RemoveEdge(GraphMtx *g,T v1,T v2);
void RemoveVertex(GraphMtx *g,T v);

//矩阵的初始化
void InitGraphMtx(GraphMtx *g)
{
    g->MaxVertices = Default_Vertex_Size;
    g->NumVertices = g->NumEdges = 0;

    g->VerticesList = (T*)malloc(sizeof(T)*g->MaxVertices);
    assert(g->VerticesList!=nullptr);

    g->Edge = (int**)malloc(sizeof(int*)*g->MaxVertices);
    assert(g->Edge!=nullptr);
    for(int i=0;i<g->MaxVertices;++i)
    {
        g->Edge[i] = (int*)malloc(sizeof(int)*g->MaxVertices);
    }
    for(int i=0;i<g->MaxVertices;++i)
    {
        for(int j=0;j<g->MaxVertices;++j)
        {
            g->Edge[i][j] = 0;
        }
    }
}
//插入点操作
void InsertVertex(GraphMtx *g,T v)
{
    if(g->NumVertices >= g->MaxVertices)
        return;
    g->VerticesList[g->NumVertices++] = v;
}
//输出矩阵
void ShowGraphMtx(GraphMtx *g)
{
    printf("  ");
    for(int i=0;i<g->NumVertices;++i)
    {
        printf("%c ",g->VerticesList[i]);
    }
    printf("\n");
    for(int i=0;i<g->NumVertices;++i)
    {
        printf("%c ",g->VerticesList[i]);
        for(int j=0;j<g->NumVertices;++j)
            printf("%d ",g->Edge[i][j]);
        printf("\n");
    }
    printf("\n");
}
//获取点的下标操作
int GetVertexPos(GraphMtx *g,T v)
{
    for(int i=0;i<g->NumVertices;i++)
    {
        if(g->VerticesList[i]==v)
            return i;
    }
    return -1;
}
//插入边操作
void InsertEdge(GraphMtx *g,T v1,T v2)
{
    int p1 = GetVertexPos(g,v1);
    int p2 = GetVertexPos(g,v2);
    if(p1==-1||p2==-1)
        return;
    if(g->Edge[p1][p2] != 0)
        return;
    g->Edge[p1][p2] = g->Edge[p2][p1] = 1;
    g->NumEdges++;
}
//删除边操作
void RemoveEdge(GraphMtx *g,T v1,T v2)
{
    int p1 = GetVertexPos(g,v1);
    int p2 = GetVertexPos(g,v2);
    if(p1 == -1 || p2 == -1)
        return;
    if(g->Edge[p1][p2]==0)
        return;
    g->Edge[p1][p2] = g->Edge[p2][p1] = 0;
    g->NumEdges--;
}
//删除点操作---包括删除与该点有联系的边
void RemoveVertex(GraphMtx *g,T v)
{
    int p = GetVertexPos(g,v);
    if(p == -1)
        return;
    for(int i=p;i<g->NumVertices-1;++i)
    {
        g->VerticesList[i] = g->VerticesList[i+1];
    }
    int numegdes = 0;
    for(int i=0;i<g->NumVertices;++i)
    {
        if(g->Edge[p][i]!=0)
            numegdes++;
    }
    for(int j=p;j<g->NumVertices-1;++j)
    {
        for(int k=0;k<g->NumVertices;k++)
        {
            g->Edge[j][k] = g->Edge[j+1][k];
        }
    }
    for(int j=p;j<g->NumVertices-1;j++)
    {
        for(int k=0;k<g->NumVertices;k++)
            g->Edge[k][j] = g->Edge[k][j+1];
    }
    g->NumVertices--;
    g->NumEdges -= numegdes;
}
//摧毁图结构
void DestroyGraph(GraphMtx *g)
{
    free(g->VerticesList);              //释放已分配的存储相应的点的空间
    g->VerticesList = NULL;
    for(int i=0;i<g->NumVertices;++i)   //二维数组,先逐个释放一级数组的存储空间
        free(g->Edge[i]);
    free(g->Edge);                      //释放二级存储空间
    g->Edge = NULL;
    g->NumEdges = g->NumVertices = g->MaxVertices = 0;      //变量值赋为0
}
//获取该点的第一个邻接顶点
int GetFirstNeighbor(GraphMtx *g,T v)
{
    int p = GetVertexPos(g,v);
    if(p == -1)
        return -1;
    for(int i=0;i<g->NumVertices;++i)
    {
        if(g->Edge[p][i] == 1)
            return i;
    }
    return -1;
}
//获取该点的第一个邻接顶点的下一个节点
int GetNextNeighbor(GraphMtx *g,T v,T w)
{
    int pv = GetVertexPos(g,v);         //获取点下标
    int pw = GetVertexPos(g,w);
    if(pv == -1 || pw ==-1)             //判断点下标的合法性
        return -1;
    for(int i=pw+1;i<g->NumVertices;++i)        //遍历与pv点有关联的点,位置从pw位置开始
    {
        if(g->Edge[pv][i] == 1)
            return i;                   //返回所要的点的下标
    }
    return -1;
}


int main()
{
    GraphMtx gm;
    //初始化
    InitGraphMtx(&gm);
    //插入点操作
    InsertVertex(&gm,'A');
    InsertVertex(&gm,'B');
    InsertVertex(&gm,'C');
    InsertVertex(&gm,'D');
    InsertVertex(&gm,'E');
    //InsertVertex(&gm,'A');

    //插入边操作
    InsertEdge(&gm,'A','B');
    InsertEdge(&gm,'A','D');
    InsertEdge(&gm,'B','C');
    InsertEdge(&gm,'B','E');
    InsertEdge(&gm,'C','D');
    InsertEdge(&gm,'C','E');
    //InsertEdge(&gm,'C','D');
    //获取该点的第一个邻接顶点
    int pos = GetFirstNeighbor(&gm,'A');
    printf("%c \n",gm.VerticesList[pos]);
    //获取该节点的下一个节点的邻接顶点
    pos = GetNextNeighbor(&gm,'A','B');
    printf("%d \n",pos);

    ShowGraphMtx(&gm);
    //删除边
    RemoveEdge(&gm,'B','C');
    ShowGraphMtx(&gm);
    //删除点
    RemoveVertex(&gm,'C');
    ShowGraphMtx(&gm);

    //摧毁图结构
    DestroyGraph(&gm);
    return 0;
}
邻接矩阵

2、图的邻接表的基本操作的实现

#include<stdio.h>
#include<malloc.h>
#include<assert.h>

#define Default_Vertex_Size 10
#define T char

typedef struct Edge
{
    int dest;
    struct Edge *link;
}Edge;

typedef struct Vertex
{
    T data;
    Edge *adj;
}Vertex;

typedef struct GraphLnk
{
    int MaxVertices;            //最大点数量
    int NumVertices;
    int NumEdges;

    Vertex *NodeTable;
}GraphLnk;


void InitGraph(GraphLnk *g);
void ShowGraph(GraphLnk *g);
void InsertVertex(GraphLnk *g,T v);
void InsertEdge(GraphLnk *g,T v,T w);


//初始化
void InitGraph(GraphLnk *g)
{
    g->MaxVertices = Default_Vertex_Size;
    g->NumEdges = g->NumVertices = 0;

    g->NodeTable = (Vertex*)malloc(sizeof(Vertex)*g->MaxVertices);
    assert(g->NodeTable!=NULL);
    for(int i=0;i<g->MaxVertices;++i)
    {
        g->NodeTable[i].adj = NULL;
    }
}
//输出图结构
void ShowGraph(GraphLnk *g)
{
    Edge *p;
    for(int i=0;i<g->NumVertices;i++)
    {
        p = g->NodeTable[i].adj;
        printf("%d %c:>",i,g->NodeTable[i].data);
        while(p != NULL)
        {
            printf("%d-->",p->dest);
            p = p->link;
        }
        printf("Nul. \n");
    }
}
//插入点结构
void InsertVertex(GraphLnk *g,T v)
{
    if(g->NumVertices>=g->MaxVertices)
        return;
    g->NodeTable[g->NumVertices++].data = v;
}

int GetVertexPos(GraphLnk *g,T v)
{
    for(int i=0;i<g->NumVertices;++i)
        if(g->NodeTable[i].data == v)
            return i;
    return -1;
}

void InsertEdge(GraphLnk *g,T v,T w)
{
    int v1 = GetVertexPos(g,v);
    int v2 = GetVertexPos(g,w);
    if(v1 == -1 || v2 == -1)
        return;
    Edge *s;
    //V1 -- V2
    s = (Edge*)malloc(sizeof(Edge));
    assert(s!=NULL);
    s->dest = v2;
    s->link = g->NodeTable[v1].adj;     //头插法 进行边节点的插入
    g->NodeTable[v1].adj = s;

    //V2 -- V1
    s = (Edge*)malloc(sizeof(Edge));
    assert(s!=NULL);
    s->dest = v1;
    s->link = g->NodeTable[v2].adj;
    g->NodeTable[v2].adj = s;
    g->NumEdges++;
}

int main()
{
    GraphLnk gl;
    //初始化
    InitGraph(&gl);
    //插入节点
    InsertVertex(&gl,'A');
    InsertVertex(&gl,'B');
    InsertVertex(&gl,'C');
    InsertVertex(&gl,'D');
    InsertVertex(&gl,'E');
    InsertVertex(&gl,'F');

    InsertEdge(&gl,'A','B');
    InsertEdge(&gl,'A','D');
    InsertEdge(&gl,'B','C');
    InsertEdge(&gl,'B','E');
    InsertEdge(&gl,'C','D');
    InsertEdge(&gl,'C','E');

    ShowGraph(&gl);

    return 0;
}
邻接表

 

posted @ 2022-07-16 19:50  往心。  阅读(51)  评论(0编辑  收藏  举报