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;
}
icoding复习6 图相关推荐
- icoding复习7, 8
icoding复习7 哈希,AVL 查找 必考点!!! 1. 哈希表创建 typedef enum{ HASH_OK, HASH_ERROR, HASH_ADDED, ...
- icoding复习5 树 感觉难度巨大....
icoding 复习5 1. 先序遍历 已知二叉树按照二叉链表方式存储,利用栈的基本操作写出先序遍历非递归形式的算法: void pre_order(BiTree root); 二叉树的相关定义如下 ...
- icoding复习4 数组 十字链表
icoding 复习4 1. 矩阵加法 实现三元组表示的两个稀疏矩阵的加法. #define MAXSIZE 100 //假设非零元个数的最大值为100 typedef struct ...
- icoding复习3
icoding复习3 1. 不调用库函数,自己实现字符串的比较操作:该操作当比较的两个字符是都是字母,且两个字符互为大小写 (如a和A.e和E)时认为两个字符相同,否则不同,其比较结果按这两个字符的原 ...
- icoding复习1,2
icoding复习 1 链表 倒数查找 1. 已知一个带有表头结点的单链表, 假设链表只给出了头指针L.在不改变链表的前提下,请设计一个尽可能高效的算法, 查找链表中倒数第k个位置上的结点(k为正整数 ...
- 2020年前端面试复习必读精选文章【赠复习导图】
前言 之前写过一篇 一年半经验如何准备阿里巴巴前端面试,给大家分享了一个面试复习导图,有很多朋友说希望能够针对每个 case 提供一个参考答案. 写答案就算了,一是精力有限,二是我觉得大家还是需要自己 ...
- github大佬呕心沥血整理的2020年前端面试复习必读精选文章【赠复习导图】
2021年前端面试必读文章[超三百篇文章/赠复习导图] 转载.原文链接 哈哈,之前是 2020 年必读文章,到了 2021 年了,感觉这些文章还都是经典,那就改个标题吧.[手动狗头] 前言 之前写过一 ...
- 有心人天不负,互联网寒冬下斩获40W年薪offer,面经分享(附复习脑图)
前言 今年年初,到了金三银四的关键时期,却频频爆出大厂裁员,互联网寒冬令人瑟瑟发抖,而本人已在三月份裸辞,跳槽压力巨大,本文就来聊聊亲身经历.包括如何复习,投简历,面试,谈薪. 复习 每次跳槽,必不可 ...
- 离散数学复习笔记——图的着色
图的着色 文章目录 图的着色 着色 点着色 常见图的点色数 Peterson图 安排期末考试问题 地图的着色与平面图的点着色 定理12.13 四色定理 边着色 排课问题 色多项式 求色数多项式 色多项 ...
最新文章
- python querystring encode_百分号 json
- oracle json入参调用ws服务返回请求失败_Spring 5.2.2技术集成 —Spring HTTP调用程序和JAXWS...
- web安全测试视频课程专题_有关有效企业测试的视频课程
- iOS 第五期考核题(字典与数组嵌套,字典的排序/删除)
- 【ElasticSearch】Es 源码之 MonitorService 源码解读
- Linux文件系统:编写一个内核文件系统
- Java设计模式----工厂模式-----简单工厂(静态工厂模式)
- 10个免费的web压力测试工具
- 输入法半角和全角的快捷转换_华宇拼音输入法 一款完全免费的国产输入法_应用新闻-产经频道-中文科技资讯...
- 通关制单机器人_智能通关云平台
- 浏览器显示json格式
- 问题解决:IndentationError: expected an indented block
- 微信 打开html文件,微信文件在电脑上打开文件
- Android 利用高德地图API进行定位、开发电子围栏、天气预报、轨迹记录、搜索周边(位置)
- headfirst 笔记 第七章
- 【多线程/线程池】项目中实际应用场景
- 【NLP基础理论】03 文本分类
- 阿里云服务器+Hexo+Nginx搭建个人博客网站
- OC入门教程-xcode第一个工程
- 讨论电子工程师的前途
热门文章
- Android之解决Gigaset手机不能设置DeviceOwner权限提示already provisioned问题
- WEB服务器 - Apache、Nnginx、Lighttpd的比较和择优(转)
- 数据库平时错误和使用经验的总结
- python123输出hello world_Python基础:输入与输出
- 那些不回微信的人,都在看什么?
- android飞翔的小鸟游戏素材包_开心消消乐×愤怒的小鸟:为开心而战
- 用wamper打开php源码_php源码该怎么设置数据库
- js请求结果拦截机器_CefSharp请求资源拦截及自定义处理
- 11尺寸长宽 iphone_LED显示屏的尺寸规格计算方法
- python xpath定位不到_Python+Selenium定位不到元素常见原因及解决办法(报:NoSuchElementException)...