数据结构和算法之如何建立图

简介: 小白BG.1 邻接矩阵表示的图结点的结构typedef struct GNode *PtrToGNode;//PtrToGNode是指向GNode的一个指针struct GNode{int Nv;//顶点数int Ne;//边数WeightType G[MaxVertexNum][MaxVertexNum];DataType Data[MaxVertexNum];//存顶点的数据};typedef PtrToGNode MGraph;//以邻接矩阵存储的图类型。定义为指向节点的指针。因为要用到的时候一个指针远远比一整个图来的快捷小白BG.2 邻接矩阵表示的图——初始化 初

小白BG.1 邻接矩阵表示的图结点的结构

typedef struct GNode *PtrToGNode;//PtrToGNode是指向GNode的一个指针

struct GNode{

int Nv;//顶点数

int Ne;//边数

WeightType G[MaxVertexNum][MaxVertexNum];

DataType Data[MaxVertexNum];//存顶点的数据

};

typedef PtrToGNode MGraph;//以邻接矩阵存储的图类型。定义为指向节点的指针。因为要用到的时候

一个指针远远比一整个图来的快捷

小白BG.2 邻接矩阵表示的图——初始化

初始化一个有VertexNum个顶点但没有边的图

typedef int Vertex;//用顶点下标表示顶点,为整型

MGraph CreateGraph(int VertexNum)//VertexNum这个顶点数真的是整数,

{

Vertex V , W;//我们在说V跟W的时候不是在说整数,而是顶点

MGraph Graph;

Graph = (MGraph)malloc(sizeof(struct GNode));

Graph->Nv = VertexNum;

Graph->Ne = 0;

//注意:这里默认顶点编号从0开始,到(Graph->Nv - 1)

for(V=0;V<Graph->Nv;V++)

for((W=0;W<Graph->Nv;W++))

Graph->G[V][M] = 0;//或者INFINITY,表示这两个顶点之间是没有边的

return Graph

}

小白BG.3 邻接矩阵表示的图——插入边

typedef struct ENode *PtrToENode;

struct ENode{

Vertex V1,V2;//有向边<V1,V2>,V1V2两个顶点一个出发点一个终点

WeightType Weight;//权重,有权图才需要。权重的类型是WeightType

};

typedef PtrToENode Edge;

void InsertEdge(MGraph Graph,Edge E)

{

//插入边<V1,V2>,这是一条边

Graph->G[E->V1][E->V2] = E->Weight;

//无向图的话还需要一条边(一共两条),<V2,V1>

Graph->G[E->V2][E->V1] = E->Weight;

}

小白BG.4 邻接矩阵表示的图——建立图

完整的建立一个MGraph

输入格式

1. Nv Ne

2. V1 V2 Weight

3. ......

MGraph BuildGraph()

{

MGraph Graph;

scanf("%d",&Nv);

Graph = CreateGraph(Nv);

//读入边数

scanf("%d",&(Graph->Ne));

if(Graph -> Ne = 0){//有边就还需要经过这里,没有边直接结束

E = (Edge)malloc(sizeof(struct ENode));//临时存一下边

for(i = 0; i < Graph->Ne; i++){

scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);

InsertEdge(Graph,E);

}

}

//如果顶点有数据的话,读入数据

for(V=0;V<Graph->Nv;V++)

scanf("%c",&(Graph->Data[V]));

return Graph;

}

简易建法

int G[MAXN][MAXN],Nv,Ne;//声明为全局变量

void BuildGraph()

{

int i,j,v1,v2,w;

scanf("%d",&Nv);

//CreateGraph

for(i=0;i<Nv;i++)

for(j=0;j<Nv;j++)

G[i][j] = 0;//或INFINITY,把矩阵所有元素先初始化为0或者无穷大

scanf("%d",&Ne);

for(i = 0;i < Ne; i++){

scanf("%d %d %d",&v1,&v2,&w);

//InsertEdge

G[v1][v2] = w;

G[v2][v1] = w;

}

}

小白BG.5 邻接表表示的图结点的结构

邻接表:G[N]为指针数组,对应矩阵每一行一个链表,只存非0元素

typedef struct GNode *PtrToGNode;

struct GNode {

int Nv;//顶点数

int Ne;//边数

AdjList G;//邻接表

};

typedef PtrToGNode LGraph;

//以邻接表方式存储的图类型

//AdjList是自己定义的

typedef struct Vnode{

PtrToAdjVNode FirstEdge;

DataType Data;//存顶点的数据

}AdjList[MaxVertexNum];//AdjList是邻接表类型

typedef struct AdjVNode *PtrToAdjVNode;

struct AdjVNode{

Vertex AdjV;//邻接点下标,定义为整型

WeightType Weight;//边权重

PtrToAdjVNode Next;

};

小白BG.6 邻接表表示的图——建立图

初始化一个有VertexNum个顶点但没有边的图

typedef int Vertex;//用顶点下标表示顶点,为整型

LGraph CreateGraph(int VertexNum)

{

Vertex V,W;

LGraph Graph;

Graph = (LGraph)malloc(sizeof(struct GNode));

Graph->Nv = VertexNum;

Graph->Ne = 0;

//没有边的意思是每个顶点跟着的那个链表都是空的

//注意:这里默认顶点编号从0开始,到(Graph->Nv - 1)

for(V=0;V<Graph->Nv;V++)

Graph->G[V].FirstEdge = NULL;

return Graph;

}

void InsertEdge(LGraph Graph,Edge E)

{

PtrToAdjVNode NewNode;

//-------------------插入边<V1,V2>------------------------------

//为V2建立新的邻接点

NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjNode));

NewNode->AdjV = E->V2;

NewNode->Weight = E->Weight

//将V2插入到V1的表头

NewNode->Next = Graph->G[E->V1].FirstEdge;

Graph->G[E->V1].FirstEdge = NewNode;

//-------------------若是无向图,还需插入边<V2,V1>------------------

//为V1建立新的邻接点

NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjNode));

NewNode->AdjV = E->V1;

NewNode->Weight = E->Weight

//将V2插入到V1的表头

NewNode->Next = Graph->G[E->V2].FirstEdge;

Graph->G[E->V2].FirstEdge = NewNode;

}

相关文章
|
5月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
158 1
|
5月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
150 0
|
9月前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
286 10
 算法系列之数据结构-二叉树
|
9月前
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
242 3
 算法系列之数据结构-Huffman树
|
9月前
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
351 22
|
10月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
362 30
|
10月前
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
455 25
|
10月前
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
590 23
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
291 59
|
6月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
123 0
栈区的非法访问导致的死循环(x64)

热门文章

最新文章