第41棵 - 图的存储结构

1. 邻接矩阵法

用一维数组存储顶点--描述顶点相关的数据。

用二维数组存储边--描述顶点的边。

设图A = (V,E)是一个有n个顶点的图,图的邻接矩阵为Edge[n][n],则:Edge[i][j] = W,W>0,i和j连接;Edge[i][j] = 0,i == j 或者i和j不链接。

注:W为权值,当需要权值时,取W为1表示结点间连接。

无向图的邻接矩阵是对称的。

有向图的邻接矩阵可能是不对称的。

2. 邻接矩阵法的头结点

记录定点的个数。

记录与顶点相关的数据描述。

记录描述边集的二维数组。

typedef struct _tag_MGraph

{

int count;

MVertex** v;

int** matrix;

}TMGraph;

问题:如何根据顶点数目,动态创建二维数组?

3. 动态申请二维数组的原理

通过二级指针动态申请一位数组。

通过一级指针申请数据空间。

将一维指针数组中的指针连接到数据空间。

int** malloc2d(int row, int col)

{

int** ret = (int**)malloc(sizeof(int*) * row);

int* p = (int*)malloc(sizeof(int) * row *col);

int i = 0;

if(p && ret)

{

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

{

ret[i] = p + i * col;

}

}

else

{

free(ret);

fre(p);

ret = NULL;

}

return ret;

}

4. 程序——邻接矩阵法实现图结构

main.c

#include <stdio.h>

#include <stdlib.h>

#include "LGraph.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void print_data(LVertex* v)

{

printf("%s", (char*)v);

}

int main(int argc, char *argv[])

{

LVertex* v[] = {"A", "B", "C", "D", "E", "F"};

LGraph* graph = LGraph_Create(v, 6);

LGraph_AddEdge(graph, 0, 1, 1);

LGraph_AddEdge(graph, 0, 2, 1);

LGraph_AddEdge(graph, 0, 3, 1);

LGraph_AddEdge(graph, 1, 5, 1);

LGraph_AddEdge(graph, 1, 4, 1);

LGraph_AddEdge(graph, 2, 1, 1);

LGraph_AddEdge(graph, 3, 4, 1);

LGraph_AddEdge(graph, 4, 2, 1);

LGraph_Display(graph, print_data);

LGraph_DFS(graph, 0, print_data);

LGraph_BFS(graph, 0, print_data);

LGraph_Destroy(graph);

return 0;

}

LGraph.h

#ifndef _LGRAPH_H_

#define _LGRAPH_H_

typedef void LGraph;

typedef void LVertex;

typedef void (LGraph_Printf)(LVertex*);

LGraph* LGraph_Create(LVertex** v, int n);

void LGraph_Destroy(LGraph* graph);

void LGraph_Clear(LGraph* graph);

int LGraph_AddEdge(LGraph* graph, int v1, int v2, int w);

int LGraph_RemoveEdge(LGraph* graph, int v1, int v2);

int LGraph_GetEdge(LGraph* graph, int v1, int v2);

int LGraph_TD(LGraph* graph, int v);

int LGraph_VertexCount(LGraph* graph);

int LGraph_EdgeCount(LGraph* graph);

void LGraph_DFS(LGraph* graph, int v, LGraph_Printf* pFunc);

void LGraph_BFS(LGraph* graph, int v, LGraph_Printf* pFunc);

void LGraph_Display(LGraph* graph, LGraph_Printf* pFunc);

#endif

LGraph.c

#include <malloc.h>

#include <stdio.h>

#include "LGraph.h"

#include "LinkList.h"

#include "LinkQueue.h"

typedef struct _tag_LGraph

{

int count;

LVertex** v;

LinkList** la;

} TLGraph;

typedef struct _tag_ListNode

{

LinkListNode header;

int v;

int w;

} TListNode;

static void recursive_dfs(TLGraph* graph, int v, int visited[], LGraph_Printf* pFunc)

{

int i = 0;

pFunc(graph->v[v]);

visited[v] = 1;

printf(", ");

for(i=0; i<LinkList_Length(graph->la[v]); i++)

{

TListNode* node = (TListNode*)LinkList_Get(graph->la[v], i);

if( !visited[node->v] )

{

recursive_dfs(graph, node->v, visited, pFunc);

}

}

}

static void bfs(TLGraph* graph, int v, int visited[], LGraph_Printf* pFunc)

{

LinkQueue* queue = LinkQueue_Create();

if( queue != NULL )

{

LinkQueue_Append(queue, graph->v + v);

visited[v] = 1;

while( LinkQueue_Length(queue) > 0 )

{

int i = 0;

v = (LVertex**)LinkQueue_Retrieve(queue) - graph->v;

pFunc(graph->v[v]);

printf(", ");

for(i=0; i<LinkList_Length(graph->la[v]); i++)

{

TListNode* node = (TListNode*)LinkList_Get(graph->la[v], i);

if( !visited[node->v] )

{

LinkQueue_Append(queue, graph->v + node->v);

visited[node->v] = 1;

}

}

}

}

LinkQueue_Destroy(queue);

}

LGraph* LGraph_Create(LVertex** v, int n)  // O(n)

{

TLGraph* ret = NULL;

int ok = 1;

if( (v != NULL ) && (n > 0) )

{

ret = (TLGraph*)malloc(sizeof(TLGraph));

if( ret != NULL )

{

ret->count = n;

ret->v = (LVertex**)calloc(n, sizeof(LVertex*));

ret->la = (LinkList**)calloc(n, sizeof(LinkList*));

ok = (ret->v != NULL) && (ret->la != NULL);

if( ok )

{

int i = 0;

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

{

ret->v[i] = v[i];

}

for(i=0; (i<n) && ok; i++)

{

ok = ok && ((ret->la[i] = LinkList_Create()) != NULL);

}

}

if( !ok )

{

if( ret->la != NULL )

{

int i = 0;

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

{

LinkList_Destroy(ret->la[i]);

}

}

free(ret->la);

free(ret->v);

free(ret);

ret = NULL;

}

}

}

return ret;

}

void LGraph_Destroy(LGraph* graph) // O(n*n)

{

TLGraph* tGraph = (TLGraph*)graph;

LGraph_Clear(tGraph);

if( tGraph != NULL )

{

int i = 0;

for(i=0; i<tGraph->count; i++)

{

LinkList_Destroy(tGraph->la[i]);

}

free(tGraph->la);

free(tGraph->v);

free(tGraph);

}

}

void LGraph_Clear(LGraph* graph) // O(n*n)

{

TLGraph* tGraph = (TLGraph*)graph;

if( tGraph != NULL )

{

int i = 0;

for(i=0; i<tGraph->count; i++)

{

while( LinkList_Length(tGraph->la[i]) > 0 )

{

free(LinkList_Delete(tGraph->la[i], 0));

}

}

}

}

int LGraph_AddEdge(LGraph* graph, int v1, int v2, int w) // O(1)

{

TLGraph* tGraph = (TLGraph*)graph;

TListNode* node = NULL;

int ret = (tGraph != NULL);

ret = ret && (0 <= v1) && (v1 < tGraph->count);

ret = ret && (0 <= v2) && (v2 < tGraph->count);

ret = ret && (0 < w) && ((node = (TListNode*)malloc(sizeof(TListNode))) != NULL);

if( ret )

{

node->v = v2;

node->w = w;

LinkList_Insert(tGraph->la[v1], (LinkListNode*)node, 0);

}

return ret;

}

int LGraph_RemoveEdge(LGraph* graph, int v1, int v2) // O(n*n)

{

TLGraph* tGraph = (TLGraph*)graph;

int condition = (tGraph != NULL);

int ret = 0;

condition = condition && (0 <= v1) && (v1 < tGraph->count);

condition = condition && (0 <= v2) && (v2 < tGraph->count);

if( condition )

{

TListNode* node = NULL;

int i = 0;

for(i=0; i<LinkList_Length(tGraph->la[v1]); i++)

{

node = (TListNode*)LinkList_Get(tGraph->la[v1], i);

if( node->v == v2)

{

ret = node->w;

LinkList_Delete(tGraph->la[v1], i);

free(node);

break;

}

}

}

return ret;

}

int LGraph_GetEdge(LGraph* graph, int v1, int v2) // O(n*n)

{

TLGraph* tGraph = (TLGraph*)graph;

int condition = (tGraph != NULL);

int ret = 0;

condition = condition && (0 <= v1) && (v1 < tGraph->count);

condition = condition && (0 <= v2) && (v2 < tGraph->count);

if( condition )

{

TListNode* node = NULL;

int i = 0;

for(i=0; i<LinkList_Length(tGraph->la[v1]); i++)

{

node = (TListNode*)LinkList_Get(tGraph->la[v1], i);

if( node->v == v2)

{

ret = node->w;

break;

}

}

}

return ret;

}

int LGraph_TD(LGraph* graph, int v) // O(n*n*n)

{

TLGraph* tGraph = (TLGraph*)graph;

int condition = (tGraph != NULL);

int ret = 0;

condition = condition && (0 <= v) && (v < tGraph->count);

if( condition )

{

int i = 0;

int j = 0;

for(i=0; i<tGraph->count; i++)

{

for(j=0; j<LinkList_Length(tGraph->la[i]); j++)

{

TListNode* node = (TListNode*)LinkList_Get(tGraph->la[i], j);

if( node->v == v )

{

ret++;

}

}

}

ret += LinkList_Length(tGraph->la[v]);

}

return ret;

}

int LGraph_VertexCount(LGraph* graph) // O(1)

{

TLGraph* tGraph = (TLGraph*)graph;

int ret = 0;

if( tGraph != NULL )

{

ret = tGraph->count;

}

return ret;

}

int LGraph_EdgeCount(LGraph* graph) // O(n)

{

TLGraph* tGraph = (TLGraph*)graph;

int ret = 0;

if( tGraph != NULL )

{

int i = 0;

for(i=0; i<tGraph->count; i++)

{

ret += LinkList_Length(tGraph->la[i]);

}

}

return ret;

}

void LGraph_DFS(LGraph* graph, int v, LGraph_Printf* pFunc)

{

TLGraph* tGraph = (TLGraph*)graph;

int* visited = NULL;

int condition = (tGraph != NULL);

condition = condition && (0 <= v) && (v < tGraph->count);

condition = condition && (pFunc != NULL);

condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);

if( condition )

{

int i = 0;

recursive_dfs(tGraph, v, visited, pFunc);

for(i=0; i<tGraph->count; i++)

{

if( !visited[i] )

{

recursive_dfs(tGraph, i, visited, pFunc);

}

}

printf("\n");

}

free(visited);

}

void LGraph_BFS(LGraph* graph, int v, LGraph_Printf* pFunc)

{

TLGraph* tGraph = (TLGraph*)graph;

int* visited = NULL;

int condition = (tGraph != NULL);

condition = condition && (0 <= v) && (v < tGraph->count);

condition = condition && (pFunc != NULL);

condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);

if( condition )

{

int i = 0;

bfs(tGraph, v, visited, pFunc);

for(i=0; i<tGraph->count; i++)

{

if( !visited[i] )

{

bfs(tGraph, i, visited, pFunc);

}

}

printf("\n");

}

free(visited);

}

void LGraph_Display(LGraph* graph, LGraph_Printf* pFunc) // O(n*n*n)

{

TLGraph* tGraph = (TLGraph*)graph;

if( (tGraph != NULL) && (pFunc != NULL) )

{

int i = 0;

int j = 0;

for(i=0; i<tGraph->count; i++)

{

printf("%d:", i);

pFunc(tGraph->v[i]);

printf(" ");

}

printf("\n");

for(i=0; i<tGraph->count; i++)

{

for(j=0; j<LinkList_Length(tGraph->la[i]); j++)

{

TListNode* node = (TListNode*)LinkList_Get(tGraph->la[i], j);

printf("<");

pFunc(tGraph->v[i]);

printf(", ");

pFunc(tGraph->v[node->v]);

printf(", %d", node->w);

printf(">");

printf(" ");

}

}

printf("\n");

}

}

LinkList.h

LinkList.c

LinkQueue.h

LinkQueue.c

5. 邻接表示法

从一个顶点出发的边连接在同一个链表中。

每一个链表结点代表一条边,结点中保存边的另一个顶点的下标和权值。

6. 邻接链表发的头结点

记录定点个数。

记录与顶点相关的数据描述。

记录描述边集的链表数组。

typedef struct _tag_LGraph

{

int count;

LVertex** v;

LinkList** la;

}TLGraph;

7. 程序——邻接链表发实现图结构

main.c

#include <stdio.h>

#include <stdlib.h>

#include "MGraph.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void print_data(MVertex* v)

{

printf("%s", (char*)v);

}

int main(int argc, char *argv[])

{

MVertex* v[] = {"A", "B", "C", "D", "E", "F"};

MGraph* graph = MGraph_Create(v, 6);

MGraph_AddEdge(graph, 0, 1, 1);

MGraph_AddEdge(graph, 0, 2, 1);

MGraph_AddEdge(graph, 0, 3, 1);

MGraph_AddEdge(graph, 1, 5, 1);

MGraph_AddEdge(graph, 1, 4, 1);

MGraph_AddEdge(graph, 2, 1, 1);

MGraph_AddEdge(graph, 3, 4, 1);

MGraph_AddEdge(graph, 4, 2, 1);

MGraph_Display(graph, print_data);

MGraph_DFS(graph, 0, print_data);

MGraph_BFS(graph, 0, print_data);

MGraph_Destroy(graph);

return 0;

}

MGraph.h

#ifndef _MGRAPH_H_

#define _MGRAPH_H_

typedef void MGraph;

typedef void MVertex;

typedef void (MGraph_Printf)(MVertex*);

MGraph* MGraph_Create(MVertex** v, int n);

void MGraph_Destroy(MGraph* graph);

void MGraph_Clear(MGraph* graph);

int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w);

int MGraph_RemoveEdge(MGraph* graph, int v1, int v2);

int MGraph_GetEdge(MGraph* graph, int v1, int v2);

int MGraph_TD(MGraph* graph, int v);

int MGraph_VertexCount(MGraph* graph);

int MGraph_EdgeCount(MGraph* graph);

void MGraph_DFS(MGraph* graph, int v, MGraph_Printf* pFunc);

void MGraph_BFS(MGraph* graph, int v, MGraph_Printf* pFunc);

void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc);

#endif

MGraph.c

#include <malloc.h>

#include <stdio.h>

#include "MGraph.h"

#include "LinkQueue.h"

typedef struct _tag_MGraph

{

int count;

MVertex** v;

int** matrix;

} TMGraph;

static void recursive_dfs(TMGraph* graph, int v, int visited[], MGraph_Printf* pFunc)

{

int i = 0;

pFunc(graph->v[v]);

visited[v] = 1;

printf(", ");

for(i=0; i<graph->count; i++)

{

if( (graph->matrix[v][i] != 0) && !visited[i] )

{

recursive_dfs(graph, i, visited, pFunc);

}

}

}

static void bfs(TMGraph* graph, int v, int visited[], MGraph_Printf* pFunc)

{

LinkQueue* queue = LinkQueue_Create();

if( queue != NULL )

{

LinkQueue_Append(queue, graph->v + v);

visited[v] = 1;

while( LinkQueue_Length(queue) > 0 )

{

int i = 0;

v = (MVertex**)LinkQueue_Retrieve(queue) - graph->v;

pFunc(graph->v[v]);

printf(", ");

for(i=0; i<graph->count; i++)

{

if( (graph->matrix[v][i] != 0) && !visited[i] )

{

LinkQueue_Append(queue, graph->v + i);

visited[i] = 1;

}

}

}

}

LinkQueue_Destroy(queue);

}

MGraph* MGraph_Create(MVertex** v, int n)  // O(n)

{

TMGraph* ret = NULL;

if( (v != NULL ) && (n > 0) )

{

ret = (TMGraph*)malloc(sizeof(TMGraph));

if( ret != NULL )

{

int* p = NULL;

ret->count = n;

ret->v = (MVertex**)malloc(sizeof(MVertex*) * n);

ret->matrix = (int**)malloc(sizeof(int*) * n);

p = (int*)calloc(n * n, sizeof(int));

if( (ret->v != NULL) && (ret->matrix != NULL) && (p != NULL) )

{

int i = 0;

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

{

ret->v[i] = v[i];

ret->matrix[i] = p + i * n;

}

}

else

{

free(p);

free(ret->matrix);

free(ret->v);

free(ret);

ret = NULL;

}

}

}

return ret;

}

void MGraph_Destroy(MGraph* graph) // O(1)

{

TMGraph* tGraph = (TMGraph*)graph;

if( tGraph != NULL )

{

free(tGraph->v);

free(tGraph->matrix[0]);

free(tGraph->matrix);

free(tGraph);

}

}

void MGraph_Clear(MGraph* graph) // O(n*n)

{

TMGraph* tGraph = (TMGraph*)graph;

if( tGraph != NULL )

{

int i = 0;

int j = 0;

for(i=0; i<tGraph->count; i++)

{

for(j=0; j<tGraph->count; j++)

{

tGraph->matrix[i][j] = 0;

}

}

}

}

int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w) // O(1)

{

TMGraph* tGraph = (TMGraph*)graph;

int ret = (tGraph != NULL);

ret = ret && (0 <= v1) && (v1 < tGraph->count);

ret = ret && (0 <= v2) && (v2 < tGraph->count);

ret = ret && (0 <= w);

if( ret )

{

tGraph->matrix[v1][v2] = w;

}

return ret;

}

int MGraph_RemoveEdge(MGraph* graph, int v1, int v2) // O(1)

{

int ret = MGraph_GetEdge(graph, v1, v2);

if( ret != 0 )

{

((TMGraph*)graph)->matrix[v1][v2] = 0;

}

return ret;

}

int MGraph_GetEdge(MGraph* graph, int v1, int v2) // O(1)

{

TMGraph* tGraph = (TMGraph*)graph;

int condition = (tGraph != NULL);

int ret = 0;

condition = condition && (0 <= v1) && (v1 < tGraph->count);

condition = condition && (0 <= v2) && (v2 < tGraph->count);

if( condition )

{

ret = tGraph->matrix[v1][v2];

}

return ret;

}

int MGraph_TD(MGraph* graph, int v) // O(n)

{

TMGraph* tGraph = (TMGraph*)graph;

int condition = (tGraph != NULL);

int ret = 0;

condition = condition && (0 <= v) && (v < tGraph->count);

if( condition )

{

int i = 0;

for(i=0; i<tGraph->count; i++)

{

if( tGraph->matrix[v][i] != 0 )

{

ret++;

}

if( tGraph->matrix[i][v] != 0 )

{

ret++;

}

}

}

return ret;

}

int MGraph_VertexCount(MGraph* graph) // O(1)

{

TMGraph* tGraph = (TMGraph*)graph;

int ret = 0;

if( tGraph != NULL )

{

ret = tGraph->count;

}

return ret;

}

int MGraph_EdgeCount(MGraph* graph) // O(n*n)

{

TMGraph* tGraph = (TMGraph*)graph;

int ret = 0;

if( tGraph != NULL )

{

int i = 0;

int j = 0;

for(i=0; i<tGraph->count; i++)

{

for(j=0; j<tGraph->count; j++)

{

if( tGraph->matrix[i][j] != 0 )

{

ret++;

}

}

}

}

return ret;

}

void MGraph_DFS(MGraph* graph, int v, MGraph_Printf* pFunc)

{

TMGraph* tGraph = (TMGraph*)graph;

int* visited = NULL;

int condition = (tGraph != NULL);

condition = condition && (0 <= v) && (v < tGraph->count);

condition = condition && (pFunc != NULL);

condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);

if( condition )

{

int i = 0;

recursive_dfs(tGraph, v, visited, pFunc);

for(i=0; i<tGraph->count; i++)

{

if( !visited[i] )

{

recursive_dfs(tGraph, i, visited, pFunc);

}

}

printf("\n");

}

free(visited);

}

void MGraph_BFS(MGraph* graph, int v, MGraph_Printf* pFunc)

{

TMGraph* tGraph = (TMGraph*)graph;

int* visited = NULL;

int condition = (tGraph != NULL);

condition = condition && (0 <= v) && (v < tGraph->count);

condition = condition && (pFunc != NULL);

condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);

if( condition )

{

int i = 0;

bfs(tGraph, v, visited, pFunc);

for(i=0; i<tGraph->count; i++)

{

if( !visited[i] )

{

bfs(tGraph, i, visited, pFunc);

}

}

printf("\n");

}

free(visited);

}

void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc) // O(n*n)

{

TMGraph* tGraph = (TMGraph*)graph;

if( (tGraph != NULL) && (pFunc != NULL) )

{

int i = 0;

int j = 0;

for(i=0; i<tGraph->count; i++)

{

printf("%d:", i);

pFunc(tGraph->v[i]);

printf(" ");

}

printf("\n");

for(i=0; i<tGraph->count; i++)

{

for(j=0; j<tGraph->count; j++)

{

if( tGraph->matrix[i][j] != 0 )

{

printf("<");

pFunc(tGraph->v[i]);

printf(", ");

pFunc(tGraph->v[j]);

printf(", %d", tGraph->matrix[i][j]);

printf(">");

printf(" ");

}

}

}

printf("\n");

}

}

LinkQueue.h

LinkQueue.c

小结:

邻接矩阵法

邻接链表法

优点:直观,容易实现。

缺点:当顶点数较多,而边数较少是浪费时间和空间。

优点:有效利用空间,非常适合边数较少的图。

缺点:实现相对复杂,不容易查找两个顶点之间的权值。

邻接矩阵法和邻接链表法的选择不是绝对的,需要根据实际情况综合考虑。

转载于:https://www.cnblogs.com/free-1122/p/11336068.html

数据--第41棵 - 图的存储结构相关推荐

  1. 数据结构之图的存储结构:邻接多重表

    图的存储结构:邻接多重表 产生条件: 邻接多重表的定义: 邻接多重表的代码定义: 删除: 性能分析: 十字链表与邻接多重表的对比 产生条件: 当用邻接矩阵法存储时:空间复杂度为O(|V|^2),太大 ...

  2. 数据结构之图的存储结构:十字链表法

    图的存储结构:十字链表法 思维导图: 产生条件: 十字链表法的定义: 十字链表法的代码定义: 性能分析: 思维导图: 产生条件: 当用邻接矩阵存储时:空间复杂度为O(|v|^2),太大 当用邻接表法存 ...

  3. 数据结构之图的存储结构:邻接表法

    图的存储结构:邻接表法 产生条件: 邻接表法的定义: 邻接表法的特点: 邻接表法的代码定义: 邻接表法与邻接矩阵法的对比: 产生条件: 当用邻接矩阵存储时:空间复杂度为O(|v|^2),太大 邻接表法 ...

  4. 数据结构之图的存储结构一及其实现

    图的存储结构 由于图的结构比较复杂,任意两个顶点之间都可能存在联系,因此无法以数据元素在存储区中的物理位置来表示元素之间的关系,即图没有顺序映像的存储结构,但可以借助数组的数据类型表示元素之间的关系. ...

  5. 数据结构——图(存储结构)

    数据结构--图 图的定义和基本术语 图的类型定义 图的存储结构 数组(邻接矩阵表示法) 网(即有权图)的邻接矩阵表示法 邻接表 邻接表表示法(链式) 图的邻接表存储表示 采用邻接表表示法创建无向网 邻 ...

  6. 图的存储结构——邻接表法

    图的存储结构--邻接表法 一.邻接表 ​ 由顶点表和边表构成,顶点表由顶点域(data)和指向第一条邻接边的指针(firstarc)构成,边表(邻接表)结点由邻接点域(adjvex)和指向下一条邻接边 ...

  7. 【数据结构——图和图的存储结构】

    目录 一.图的定义和基本术语(Graph) (一)图的定义 (二)图的基本术语 一.图的存储结构 (一)邻接矩阵(Adjacency Matrix) 1.无向图的邻接矩阵 2.有向图的邻接矩阵 3.网 ...

  8. 数据结构考研笔记(十五)——图的存储结构邻接矩阵、邻接表、十字链表、临界多重表的概念

    图的存储结构 1.邻接矩阵 1.1有向图 1.2无向图 2.邻接表法 2.1有向图边表 2.2无向图边表 3.十字链表 4.临界多重表 十字链表与临界多重表 1.邻接矩阵 邻接矩阵法结点数为n的图G ...

  9. 图的存储结构(邻接矩阵和邻接表)

    图的存储结构(邻接矩阵和邻接表) 前言: 前面我们学习图的有些定义和术语,对图这个数据结构有了新的见解和认知,让我们理解图结构的知识,今天我们学习图的存储结构,图的存储结构比较多,我们今天主要是学习邻 ...

  10. 图——图的存储结构(邻接矩阵和邻接表法)

    图的五种存储结构: 1.图的邻接矩阵表示法 图是由顶点和边或弧两部分组成.图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组表示图,一个一维数组存储图中的顶点信息,一个二维数组(邻接 ...

最新文章

  1. windows命令行设置环境变量
  2. Java 正则表达式中为什么反斜杠“\“需要用“\\\\”表示
  3. SSM(Spring4.x.x+SpringMVC4.x.x+Mybatis3.4.x)框架整合
  4. 每天一道LeetCode-----将数值数组按一定顺序拼接,使得拼接的结果最大
  5. 如何用栈实现浏览器的前进和后退?
  6. PAT甲级题解-1100. Mars Numbers (20)-字符串处理
  7. hana 查看表字段_hana 查看表数据库
  8. Web Components 系列(五)—— 详解 Slots
  9. javascript---淡入淡出的效果轮换转播后续
  10. 软件开发javascript html实现网页版日历代码_javascript技巧
  11. Android 字符串的替换字符
  12. 逐帧动画案例(奔跑的小人)
  13. 服务器2012系统登录密码忘记6,Server2012忘记管理员密码的处理方法
  14. mysql 经纬度范围_MySQL之根据经纬度查询多少公里范围内的数据
  15. pythonrender函数_Render函数
  16. html5 文字滑动效果,jQuery滑动文字特效
  17. 超全Android中高级面试复习大纲,挥泪整理面经
  18. python单片机自动浇花_【应用教程】Micro:bit自动浇花系统
  19. MySQL视图 视图的作用、视图常用语法
  20. 利用python画梯形图案例

热门文章

  1. Hadoop组件之Yarn
  2. android clipRect 用法说明
  3. 25 亿条/秒消息处理!Flink 又双叒叕被 Apache 官方提名
  4. python基础篇 —— 类
  5. buck变换器设计matlab_电力电子变换器控制设计(1)
  6. java客户端实验_java实验(客户端) 2015106宋世超
  7. c语言 camp;gt与camp;lt,那位高人告诉我怎么复习c语言二级啊?????
  8. window xp系统安装php环境_在Windows XP下安装Apache+MySQL+PHP环境
  9. arcgis dem栅格立体感_arcgis中DEM如何生成等高线
  10. java文件读取的几个操作-1