邻接表:删除一个顶点(完全改变了图的邻接链表的结构)

83 篇文章 5 订阅
67 篇文章 2 订阅

问题描述 :

目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT)。

内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)

(2)设计并实现一个算法,在已存在的图中查找指定元素值的结点,如查找成功,则删除之(包括与之相关的边);否则,返回。图的存储结构采用邻接表。将其加入到ADT中。

注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)

参考函数原型:

//往G中删除一个顶点

template<class TypeOfVer, class TypeOfEdge>

bool adjlist_graph<TypeOfVer, TypeOfEdge>::DeleteVer(const int u);
输入说明 :

建图的输入数据格式参见建图的算法说明。

第一行:图的类型

第二行:结点数

第三行:结点集

第四行:边数

第五行:边集

第六行:待删除的顶点的位序

输出说明 :

第一行:图的类型

第三行:删除前的顶点数

第四行:删除前的边数

第五行:删除前的邻接表

           空行

第六行:删除后的顶点集

第七行:删除后的顶点数

第八行:删除后的边数

第九行:删除后的邻接表

输入范例 :
DG
6
A B C D E F
8
0 1
0 2
0 3
1 4
2 4
3 5
4 1
5 1
1
输出范例 :
DG
A B C D E F
6
8
A->3->2->1
B->4
C->4
D->5
E->1
F->1

A C D E F
5
4
A->2->1
C->3
D->4
E
F
思路分析
  • 整理旧的图形结构,在整体移动到新的邻接表中,不如在将旧的邻接表中的结点移动到新的邻接表中,在移动的过程中对其进行更改。
  • 新建一个新的顶点表,将原来的顶点表除了需要被删除的顶点全部复制过去
  • 遍历新的顶点表的边表,如果其索引大于待删除目标节点的索引,就减一
  • 如果是目标结点:就删除该结点
  • 如果比目标节点小,那就不用删除
实现伪码
/*
    描述:在G中删除一个顶点
*/
bool DeleteVer(const int u) {

    //注意分类,有向图和无向图

    //判定输入的位序是否合理
    if(u<0 ||u >= Vers) return false;

    //在位序合理的情况下,进行判定
    //申请新的内存
    verNode *verListTemp = new verNode[Vers-1];
    edgeNode *temp = NULL,*temp2 = NULL;
    int m = 0;//用来指向新的生成的邻接表

    //指定位序之前的结点只需要修改的边表,不需要修改自身的位序
    for(int i = 0; i < Vers; i ++) {
        //遍历的每一个结点
        //判定当前的结点是否为需要删除的目标节点的索引
        if(i == u) {
            //遍历改边表对应的边数量,总的边数减去该边数
            if(GraphKnd == "DG" || GraphKnd == "DN") {
                temp = verList[i].getHead();
                while(temp) {
                    Edge --;
                    temp = temp->next;
                }
            }
            continue;
        } else {
            //在不是要删除的目标结点的情况下,将结点复制到新生成的目标节点中
            verListTemp[m] = verList[i];
            verList[i].setHead(NULL);

            //开始遍历当前的边表
            //判定第一个结点是不是的要删除的结点
            temp = verListTemp[m].getHead();
            if(temp->getData() == u) {
                verListTemp[m].setHead(temp->next);
                Edge --;
                delete temp;
            } else {
                //开始有头结点的单链表的遍历
                while(temp) {

                    //查看当前节点的位序是否比目标结点的位序大
                    if(temp->getData() > u) {
                        temp->SetData(temp->getData() - 1);
                    }
                    //如果当前结点的下一个子节点是目标节点,就删除下一个结点
                    if(temp->next && temp->next->getData() == u) {
                        Edge --;
                        temp2 = temp->next;
                        temp->next = temp2->next;
                        delete temp2;
                    }
                    temp = temp->next;
                }
            }
            m ++;
        }
    }
    Vers --;
    delete[] verList;
    verList = verListTemp;
}
事故现场
两次提交

在这里插入图片描述

  • 有点疑惑,有向图和无向图的删除顶点不都一个意思吗?都是删除定点表,然后删除各个顶点的边表。这里直接看样例的

  • 问题:
    在这里插入图片描述

  • 无向图的边数是有两个顶点进行标识,删除一个顶点可以通过删除与之相邻接的顶点的边表进行删除,达到减去对应的边数的目的

  • 但是有向图的顶点是通过一个顶点进行标识的,一个边只有一个顶点进行标识,删除顶点要删除该顶点对应的边表的边,同时删除边表要减去对应的边

第三次提交

在这里插入图片描述

  • 这验证了我的猜想
第四次提交

在这里插入图片描述

分析总结
  • 这道题我觉得一点都不简单,我做了好久,不过也有一点经验了。基本上都是建立在已有的基础上,在已有的基础上根据题目要求对其进行修改。
  • 基本思路是遍历,根据遍历的当前节点的情况,采取不同的措施
  • 有一个措施是删除,链表删除结点,采用的是无头结点链表删除结点
  • 然后进行整合就行了
一周七门考试,完蛋了,加油哈,后面的写的简单一点吧
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值