icoding复习6 图

icoding复习6 

1. 邻接表1
试在邻接表存储结构上实现图的基本操作 insert_vertex 和 insert_arc,相关定义如下:
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 insert_vertex(ListGraph *G, VertexType v);
bool insert_arc(ListGraph *G, VertexType v, VertexType w);
当成功插入顶点或边时,函数返回true,否则(如顶点或边已存在、插入边时顶点v或w不存在)返回false。

//写下locate函数
int locate_vertex(ListGraph *G, VertexType v){
    int i;
    for(i = 0; i < G->vexnum; i++)
        if(G->vertex[i].data == v)
            return i;
    return -1;


#include
#include
//记得加这个头文件消除黄色警告 
#include "graph.h" //请勿删除,否则检查不通过
bool insert_vertex(ListGraph *G, VertexType v){
    int  i = 0;
    //2个易错点: 指针置空,可以省略; 点运算符!!务必区分 
    i = locate_vertex(G, v);
    if(i != -1) return false;
    G->vertex[G->vexnum].data = v;
    G->vertex[G->vexnum].firstarc = NULL;
    G->vexnum++;
    return true; 
}

bool insert_arc(ListGraph *G, VertexType v, VertexType w){
    int i = locate_vertex(G, v);
    int j = locate_vertex(G, w);
    
    //点不存在 
    if(i == -1 || j == -1) return false;
    //边已经存在
    ArcNode *p = G->vertex[i].firstarc;
    for(; p; p = p->nextarc)
        if(p->adjvex == j)
            return false; 
        
    ArcNode *q;
    p = G->vertex[i].firstarc;
    if(!(q = (ArcNode *)malloc(sizeof(ArcNode)))) return false;    
    q->adjvex = j;
    if(!p){
        G->vertex[i]->firstarc = q;
        q->nextarc = NULL;
    }
    else{
        q->nextarc = p->nextarc;
        p->nextarc = q; 
    }
    G->arcnum++; 
    return true;
}

//第一次的思路
bool insert_arc(ListGraph *G, VertexType v, VertexType w){
    int i, j;
    ArcNode *p;
    
    i = locate_vertex(G, v);
    j = locate_vertex(G, w);
    
    //判结点是否存在,不存在就返回false 
    if(i == -1|| j == -1)
        return false;
        
    //判边是否存在,存在就返回false 
    //需要注意的是p->adjvex = j这个判断条件,一个是int类型,一个是不要把这个判断条件放到for里面 
    for(p = G->vertex[i].firstarc;  p; p = p->nextarc)
        if(p->adjvex == j)     return false;
    
    //!!!!!需要注意的是这里是单项插入,不考虑有向无向
    //插入到方向就是v-->w 
//    for(p = G->vertex[j].firstarc;  p; p = p->nextarc)
//    if(p->adjvex == i)  return false;

    
//    if(G->type == UDG){
//        p->nextarc = G->vertex[j].firstarc->nextarc;
//        p->adjvex = v;
//        G->vertex[j].firstarc = p; 
//    }

//!!!别忘了分配空间,这个是建立一个新的节点 
    p = (ArcNode *)malloc(sizeof(ArcNode));
    p->adjvex = j;
    G->arcnum++; 
    if(!G->vertex[i].firstarc)//空的情况 
        G->vertex[i].firstarc = p;
    else{//头插 G->vertex[i].firstarc是头结点 
        p->nextarc = G->vertex[i].firstarc->nextarc;
        G->vertex[i].firstarc = p;
    }
    return true;    

2. 邻接表2

试在邻接表存储结构上实现图的基本操作 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  
#include
#include "graph.h" //请勿删除,否则检查不通过
bool del_vertex(ListGraph* G, VertexType v){
    int i = locate_vertex(G, v), j;
    if(i == -1) return false;
    j = i;
    ArcNode *p, *q;
    
    
    for(p = G->vertex[i].firstarc; p;){
        q = p;
        p = p->nextarc;
        free(q);
        G->arcnum--;
    } 
    free(G->vertex[i].firstarc); G->arcnum--;//在最后丢表头, 注意点, 这里不能理解为没有数据的头结点 
    
    for(; i < G->vexnum; i++)
        G->vertex[i] = G->vertex[i+1];
    G->vexnum--;
    
    for(i = 0; i < G->vexnum; i++){
        for(p = G->vertex[i].firstarc, q = p; p->adjvex != j && p ;q = p, p = p->nextarc)
            ;
        if(p->adjvex == j){
            if(p == G->vertex[i].firstarc)
                G->vertex[i].firstarc = p->nextarc;//隐含q == p 
            else
                q->nextarc = p->nextarc;
            free(p);
            G->arcnum--;
        } 
    }
}

//答案如下 
//思路整理
//1. 定位该节点是否存在,若存在
//2. 删除该结点以之为弧尾的链表, 挨着删,最后删除表头, 边数减少 
//3. 结点序列前移, 结点总数减少 
//4. 遍历邻接表找以删除结点为弧头的链, 删除... 
bool del_vertex(ListGraph* G, VertexType v)
{
    int i, j = locate_vertex(G, v);
    if (j == -1) //检查是否存在该节点
        return false; 
    
    //先删除从该节点出发的边和该节点
    while (G->vertex[j].firstarc) { 
        ArcNode* p = G->vertex[j].firstarc;
        if (p->nextarc) { //先free表头结点后面的
            ArcNode* q = p->nextarc;
            p->nextarc = q->nextarc;
            free(q);
        } else {
            free(p); //free表头结点
            G->vertex[j].firstarc = NULL;
        }
        G->arcnum--; //边的数量-1
    }
    G->vexnum--; //结点的数量-1
    for (i = j; i < G->vexnum; i++) { //表头结点中,后面的向前移动
        G->vertex[i] = G->vertex[i + 1];
    }
    
    //再删除到该节点的边
    for (i = 0; i < G->vexnum; i++) {
        ArcNode *p = G->vertex[i].firstarc, *pNode = NULL;
        ArcNode* q; //存储要被删掉的结点
        while (p) {
            if (p->adjvex == j) { //P的下个结点是V
                if (!pNode) { //P是表头结点
                    q = G->vertex[i].firstarc;
                    G->vertex[i].firstarc = p->nextarc;
                }
                else {
                    pNode->nextarc = p->nextarc;
                    q = p;
                }
                p = p->nextarc;
                free(q);
                G->arcnum--;
            } else {
                pNode = p;
                p = p->nextarc;
            }
        }
    }
    return true;
}

3. 邻接矩阵

试在邻接矩阵存储结构上实现图的基本操作 matrix_insert_vertex 和matrix_insert_arc,相关定义如下:

typedef int VertexType;

typedef enum{
    DG, UDG
}GraphType;

typedef struct{
    VertexType vertex[MAX_VERTEX_NUM]; //顶点向量
    int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
    int vexnum, arcnum;   //图的当前顶点数和弧数
    GraphType type;     //图的种类标志
}MatrixGraph;

int matrix_locate_vertex(MatrixGraph *MG, VertexType vex); //返回顶点 v 在vertex数组中的下标,
//如果v不存在,返回-1
bool matrix_insert_vertex(MatrixGraph *G, VertexType v);
bool matrix_insert_arc(MatrixGraph *G, VertexType v, VertexType w);
当成功插入顶点或边时,函数返回true,否则(如顶点或边已存在、插入边时顶点v或w不存在)返回false。

#include  
#include "graph.h" // 请不要删除,否则检查不通过

bool matrix_insert_vertex(MatrixGraph *G, VertexType v){
    int i = matrix_locate_vertex(G, v);
    
    if(i != -1 || G->vexnum == MAX_VERTEX_NUM - 1) return false;
    
    G->vertex[G->vexnum] = v;
    for(i = 0; i < G->vexnum; i++){
        G->arcs[G->vexnum][i] = 0;
        G->arcs[i][G->vexnum] = 0;
    }
    G->arcnum++;
    return true;
}

bool matrix_insert_arc(MatrixGraph *G, VertexType v, VertexType w){
    int i = matrix_locate_vertex(G, v);
    int j = matrix_locate_vertex(G, w);
    
    if(i == -1 || j == -1 || G->arcs[i][j] == 1) return false;
//如果加上判断图的类型 
//    if(G->type == UDG &&( G->arcs[i][j] == 1 || G->arcs[j][i] == 1))
//        return false;
//    else if(G->arcs[i][j] == 1)    
//        return false;
    G->arcs[i][j] = 1;
    if(G->type == UDG)
        G->arcs[j][i] = 1;
    G->arcnum++;
    return true;
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python帮助系统函数_【Python】【基础知识】【内置函数】【help的使用方法】

原英文帮助文档&#xff1a;help([object])Invoke the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the interpreter console. If the argument is a string, then the string i…

统计二进制数-dp

题目描述 输入一个正整数m,请输出从0到m中每一个数字二进制数中含有1的个数的总和,由于数值较大结果需要模100000. 输入格式 一个m 输出格式 二进制数中含有1的个数的总和s 输入输出样例 输入 2 输出 2 输入 5 输出 7 说明/提示 样例说明 20%的数据 m<500 50%的数据 m<…

.net 微服务实践

l 前言本文记录了我的一次.net core 微服务架构实践经验&#xff0c;以及所用到的技术l 优点每个服务聚焦于一块业务&#xff0c;无论在开发阶段或是部署阶段都是独立的&#xff0c;更适合被各个小团队开发维护&#xff0c;团队对服务的整个生命周期负责&#xff0c;工作在独…

icoding复习3

icoding复习3 1. 不调用库函数&#xff0c;自己实现字符串的比较操作&#xff1a;该操作当比较的两个字符是都是字母&#xff0c;且两个字符互为大小写 &#xff08;如a和A、e和E&#xff09;时认为两个字符相同&#xff0c;否则不同&#xff0c;其比较结果按这两个字符的原值…

redis过期监听性能_基于Redis的延迟处理

延迟处理是一个非常常用的一个功能;例如, 下单成功后,在30分钟内没有支付,自动取消订单;延迟队列便是延迟处理中最常见的实现方式;先一起看下JDK中延迟队列是如何实现的.JUC的DelayQueue在JDK中, 提供了一套延迟队列的实现, 是JUC包中DelayQueue类.在使用时只需要让处理的元素对…

洛谷 P2040 打开所有的灯-dfs

题目背景 pmshz在玩一个益(ruo)智(zhi)的小游戏&#xff0c;目的是打开九盏灯所有的灯&#xff0c;这样的游戏难倒了pmshz。。。 题目描述 这个灯很奇(fan)怪(ren)&#xff0c;点一下就会将这个灯和其周围四盏灯的开关状态全部改变。现在你的任务就是就是告诉pmshz要全部打开这…

icoding复习4 数组 十字链表

icoding 复习4 1. 矩阵加法 实现三元组表示的两个稀疏矩阵的加法。 #define MAXSIZE 100 //假设非零元个数的最大值为100 typedef struct { int i,j; //非零元的行下标和列下标&#xff0c;i 和 j 从 1 开始计数&#xff0c;与数学中矩阵元素的…

【译】来看看WebWindow,一个跨平台的.NET Core webview 库

本文翻译自 ASP.NET 项目组的 Steve Sanderson 的博客&#xff0c;发表于 2019 年 11 月 18 日。Steve Sanderson 是 Blazor 最早的创造者。它类似于 Electron&#xff0c;但没有捆绑 Node.js 和 Chromium&#xff0c;也没有大部分 API。我的上一篇文章研究了如何用 web 渲染的…

sql if 和insert_拼多多面试:Mybatis是如何实现SQL语句复用功能的?

在工作中&#xff0c;往往有这样的需求&#xff0c;对于同一个sql条件查询&#xff0c;首先需要统计记录条数&#xff0c;用以计算pageCount&#xff0c;然后再对结果进行分页查询显示&#xff0c;看下面一个例子。<sql id"studentProperties"><!--sql片段-…

上元节的灯会(亮)-dfs

题目背景 上元佳节&#xff0c;庙会里举办着各式各样的庆典活动&#xff0c;牛宝也兴奋地参与其中。突然&#xff0c;他被一个新颖的点灯游戏所吸引&#xff0c;游戏要求最终点亮所有在场的花灯&#xff0c;每盏灯都有开关两种状态&#xff0c;每一次点击在场的一盏任意状态的花…

代码演示C#各版本新功能

代码演示C#各版本新功能C#各版本新功能其实都能在官网搜到&#xff0c;但很少有人整理在一起&#xff0c;并通过非常简短的代码将每个新特性演示出来。代码演示C#各版本新功能C# 2.0版 - 2005泛型分部类型匿名方法可以为null的值类型迭代器协变和逆变C# 3.0版 - 2007自动实现的…

icoding复习5 树 感觉难度巨大....

icoding 复习5 1. 先序遍历 已知二叉树按照二叉链表方式存储&#xff0c;利用栈的基本操作写出先序遍历非递归形式的算法&#xff1a; void pre_order(BiTree root); 二叉树的相关定义如下&#xff1a; typedef int DataType; typedef struct Node{ DataType data; …

python 进行一元线性回归并输出相关结果_Python实现一元线性回归实战

回归是一种有监督的学习方式&#xff0c;需要根据历史数据对未知数据做出预测。在此&#xff0c;以房屋面积预测房屋价格为例&#xff1a;首先&#xff0c;读入数据&#xff1a;代码如下&#xff1a;import pandas as pdimport numpy as npfrom io import StringIOfrom sklearn…

《C++ Primer》第一章的 Sales_item.h头文件源码

Sales_item.h不是C自带的&#xff0c;需要自己安装&#xff0c;这个库作者已经写好了, Sales_item.h 头文件代码如下&#xff1a; #ifndef SALESITEM_H #define SALESITEM_H #include <iostream> #include <string>class Sales_item{ public:Sales_item(const std…

icoding复习7, 8

icoding复习7 哈希,AVL 查找 必考点!!! 1. 哈希表创建 typedef enum{ HASH_OK, HASH_ERROR, HASH_ADDED, HASH_REPLACED_VALUE, HASH_ALREADY_ADDED, HASH_DELETED, HASH_NOT_FOUND, } HASH_RESULT; typedef struct __HashEntry HashEntry; struc…

python加载模型包占用内存多大_加载pickle python对象会占用大量内存

我有一个python的pickle对象,它生成一个180 Mb的文件.当我取消它时,内存使用量会爆炸到2或3Gb.你有类似的经历吗&#xff1f;这是正常的吗&#xff1f;对象是包含字典的树&#xff1a;每个边是一个字母,每个节点都是一个潜在的单词.因此,要存储一个单词,您需要的边数与该单词的…

《C++ Primer》1.52节练习

练习1.23 #include <iostream> #include "Sales_item.h"using namespace std;int main() {Sales_item trans1, trans2;cout << "请输入若干销售记录:" << endl;if (cin >> trans1) {int num 1;while (cin >> trans2)if (t…

ASP.NET Core 反向代理部署知多少

引言最近在折腾统一认证中心&#xff0c;看到开源项目[IdentityServer4.Admin&#xff1a;https://github.com/skoruba/IdentityServer4.Admin]集成了IdentityServer4和管理面板&#xff0c;就直接拿过来用了。在尝试Nginx部署时遇到了诸如虚拟目录映射&#xff0c;请求头超长、…

函数传参string_JavaScript 高阶函数入门浅析

原文&#xff1a;https://www.freecodecamp.org/news/a-quick-intro-to-higher-order-functions-in-javascript-1a014f89c6b/译者&#xff1a;jingruzhang校对者&#xff1a;acusp高阶函数高阶函数可以接收函数作为参数&#xff0c;同时也可以返回一个新的函数。高阶函数之所以…

all()与any()

all():当可迭代对象为空时返回True。或者当可迭代对象中是否所有值都为True&#xff0c;所有值都为True,则返回True。否则返回False。any():当可迭代对象为空时返回False。或者当可迭代对象中是否存在一个为True的值&#xff0c;若存在&#xff0c;返回True,否则返回False 示例…