icoding数据结构——邻接表2(详细注释)

文章描述了如何在基于邻接表的图数据结构上实现删除顶点的操作。首先通过`locate_vertex`函数找到顶点的位置,然后删除与该顶点相关的所有边,接着调整顶点数组,最后更新所有其他顶点的邻接表以反映顶点的删除。代码中详细展示了这一过程。
摘要由CSDN通过智能技术生成

题目:

试在邻接表存储结构上实现图的基本操作 del_vertex,相关定义如下:

typedef int VertexType;

typedef enum{
    DG, UDG
}GraphType;

typedef struct ArcNode{
    int adjvex;
    InfoPtr *info;
    struct ArcNode *nextarc;
}ArcNode;

typedef struct VNode{
    VertexType data;
    ArcNode *firstarc;
}VNode;
typedef struct{
    VNode vertex[MAX_VERTEX_NUM];
    int vexnum, arcnum;
    GraphType type;
}ListGraph;

int locate_vertex(ListGraph *G, VertexType v); //返回顶点 v 在vertex数组中的下标,如果v不存在,返回-1
bool del_vertex(ListGraph *G, VertexType v); //删除顶点 v

当成功删除顶点或边时,函数返回true,否则(如顶点或边不存在、删除边时顶点v或w不存在)返回false。

代码:

#include <stdio.h>
#include<stdlib.h>
#include "graph.h" //请勿删除,否则检查不通过

bool del_vertex(ListGraph* G, VertexType v) {
    // 找到顶点在图中的位置
    int v1 = locate_vertex(G, v);
    if (v1 == -1) {
        return false; // 顶点不存在,返回false
    }

    // 删除与该顶点相关的边
    ArcNode* p1 = G->vertex[v1].firstarc; // 指向顶点的第一条边
    while (p1 != NULL) {
        ArcNode* temp = p1; // 保存当前边的指针
        G->vertex[v1].firstarc = p1->nextarc; // 修改顶点的第一条边指针
        p1 = p1->nextarc; // 指向下一条边
        free(temp); // 释放当前边的内存
        G->arcnum--; // 边数减一
    }

    // 删除顶点数组中该顶点
    for (int i = v1; i < G->vexnum; i++) {
        G->vertex[i] = G->vertex[i + 1];
    }
    G->vexnum--; // 顶点数减一

    // 更新其他顶点的邻接表
    ArcNode* p = NULL;
    for (int i = 0; i < G->vexnum; i++) {
        p = G->vertex[i].firstarc;
        while (p != NULL) {
            if (p->adjvex > v1) { // 由于之前删除顶点数组中该顶点时移动了顶点数组中的元素,所以要更新链表中所有>v1的编号
                p->adjvex--; // 更新顶点位置,减一
                p = p->nextarc;               
            } else if (p->adjvex == v1) {
                // 找到与顶点v相关的边
                if (G->vertex[i].firstarc == p) {
                    // 删除顶点v是第一条边的情况
                    ArcNode* temp = p;
                    G->vertex[i].firstarc = p->nextarc; // 修改顶点的第一条边指针
                    p = p->nextarc; // 指向下一条边
                    free(temp); // 释放当前边的内存
                } else {
                    // 删除顶点v不是第一条边的情况
                    ArcNode* pre = G->vertex[i].firstarc;
                    while (pre->nextarc != p) {
                        pre = pre->nextarc;
                    }
                    ArcNode* temp = p;
                    pre->nextarc = p->nextarc; // 修改前一条边的指针
                    p = p->nextarc; // 指向下一条边
                    free(temp); // 释放当前边的内存
                }
                G->arcnum--; // 边数减一
            } else {
                p = p->nextarc;
            }
        }
    }
    return true; // 删除成功,返回true
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值