数据结构与算法(7-1)图的存储(邻接矩阵、邻接表)
目录
一、图的邻接矩阵
存储结构
总代码
二、网图的邻接矩阵
存储结构
总代码
三、图的邻接表
存储结构
1、顶点列表结构体
2、邻接顶点结构体
总代码
四、网图的邻接表
存储结构
1、顶点列表结构体
2、邻接顶点结构体
总代码
一、图的邻接矩阵
存储结构
顶点数组:存储顶点数据
边数组:存储边数据
typedef struct
{char vertex[MAXSIZE]; //顶点int edge[MAXSIZE][MAXSIZE]; //邻接顶点int vertexNum; //顶点数量
}Graph;
Graph G;
总代码
//无/有向图的邻接矩阵
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>#define MAXSIZE 20typedef struct
{char vertex[MAXSIZE]; //顶点int edge[MAXSIZE][MAXSIZE]; //邻接顶点int vertexNum; //顶点数量
}Graph;
Graph G;//输入顶点
void InputVertex()
{int i = 0;char ch;printf("请输入需要创建的图顶点(不需要空格):\n");do{scanf("%c", &ch);if (ch != '\n')G.vertex[i++] = ch;} while (ch != '\n');G.vertexNum = i;
}//查找(根据结点找索引)
int findIndex(char ch)
{int i;for (i = 0; i < G.vertexNum; i++){if (G.vertex[i] == ch)return i;}return -1; //没找到
}//创建图
void InputEdge()
{int i, index;char ch;for (i = 0; i < G.vertexNum; i++){printf("请输入%c指向的邻接结点:\n", G.vertex[i]);scanf("%c", &ch);while (ch != '\n'){index = findIndex(ch); //查找输入结点的索引G.edge[i][index] = 1;scanf("%c", &ch);}}
}//输出测试
void Print()
{int i, j;for (i = 0; i < G.vertexNum; i++){printf("\n%c结点的邻接结点为:\t", G.vertex[i]);for (j = 0; j < G.vertexNum; j++){if (G.edge[i][j] != 0)printf("%c\t", G.vertex[j]);}}
}int main()
{//创建图InputVertex();InputEdge();//输出测试Print();return 0;
}
二、网图的邻接矩阵
存储结构
顶点数组:存储顶点数据
边数组:存储边数据
网图与图相比多了一个“权”,可以理解为距离。
边数组中对角线为0:因为对角线表示的是指向自身,自身到自身的距离自然是0。
到其他相邻结点距离为:权。
到其他不相邻结点距离为:无穷大(可以用计算机允许的尽可能大的数据代替无穷大)。
总代码
//邻接矩阵(无向网图)
#include<iostream>
#include<stdio.h>
using namespace std;#define MAXSIZE 20
#define MAX 65535 //无穷大typedef struct Graph
{char vertex[MAXSIZE]; //顶点int arc[MAXSIZE][MAXSIZE]; //边 (权存放在其中)int numVertex, numArc; //顶点数、边数
}Graph;
Graph G;void Input()
{cout << "请输入需要创建的顶点数量和边的数量:\n";cin >> G.numVertex >> G.numArc;
}//初始化
void Init_Graph()
{int i, j;//给数组赋0for (i = 0; i < G.numVertex; i++){for (j = 0; j < G.numVertex; j++){G.arc[i][j] = MAX; //先把所有元素赋为无穷大}G.arc[i][i] = 0; //对角线元素}
}//创建无向图
void CreateGraph()
{int i, j, num, index = 0;for (i = 0; i < G.numVertex; i++){printf("请输入第%d个结点及相邻结点数量:\n", i + 1);getchar();cin >> G.vertex[i] >> num;if (num > 0)printf("请分别输入相邻结点下标和权(空格分隔):\n", num);for (j = 0; j < num; j++){getchar();cin >> index;cin >> G.arc[i][index];}}
}//遍历
void Traverse()
{int i, j;for (i = 0; i < G.numVertex; i++){for (j = 0; j < G.numVertex; j++)printf("%d\t", G.arc[i][j]);cout << endl;}
}int main()
{Input();Init_Graph();CreateGraph(); //创建Traverse(); //遍历return 0;
}
三、图的邻接表
存储结构
无向图邻接表:
有向图邻接表:
1、顶点列表结构体
//顶点列表
typedef struct VertexList
{int index; //索引char data; //数据EdgeNode* firstedge; //指向第一个邻接结点
}VertexList;
VertexList L[MAXSIZE];
2、邻接顶点结构体
//邻接顶点
typedef struct EdgeNode
{int index; //邻接结点索引char data; //邻接结点数据struct EdgeNode* next; //指向下一个邻接结点
}EdgeNode;
总代码
//图的邻接表
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;#define MAXSIZE 100
int listLength = 0;//邻接顶点
typedef struct EdgeNode
{int index; //邻接结点索引char data; //邻接结点数据struct EdgeNode* next; //指向下一个邻接结点
}EdgeNode;//顶点列表
typedef struct VertexList
{int index; //索引char data; //数据EdgeNode* firstedge; //指向第一个邻接结点
}VertexList;
VertexList L[MAXSIZE];//输入
void Input()
{int i = 0;char ch = ' ';cout << "请输入需要创建的结点:\n";scanf_s("%c", &ch, 1);for (i = 0; i < MAXSIZE && ch != '\n'; i++){L[i].data = ch;scanf_s("%c", &ch, 1);}listLength = i; //获取列表长度(吸收空格)
}void InitList()
{int i;for (i = 0; i < listLength; i++)L[i].firstedge = NULL;
}//查找
int find(char ch)
{int i;for (i = 0; i < listLength; i++){if (ch == L[i].data)return ch;}return NULL;
}//初始化列表
void Create_List()
{int i;char ch, choice;EdgeNode* N = NULL;for (i = 0; i < listLength; i++){printf("%c是否有邻接结点?(Y/N)\n", L[i].data);scanf_s("%c", &choice, 1);getchar();if (choice == 'y' || choice == 'Y'){L[i].firstedge = (EdgeNode*)malloc(sizeof(EdgeNode));N = (EdgeNode*)malloc(sizeof(EdgeNode));N = L[i].firstedge; //连接printf("请输入%c的邻接结点:\n", L[i].data);while (1){scanf_s("%c", &ch, 1);if (ch == '\n')break;else if (ch == ' ')continue;N->data = ch; //值N->index = find(ch); //查找并赋值索引N->next = (EdgeNode*)malloc(sizeof(EdgeNode)); //下一个N = N->next;}N->next = NULL;}}
}void Print()
{int i;EdgeNode* N = NULL;for (i = 0; i < listLength; i++){printf("\n%c的邻接结点:", L[i].data);N = L[i].firstedge;while (N){cout << N->data;N = N->next;}cout << endl;}
}int main()
{Input();InitList();Create_List();Print();return 0;
}
四、网图的邻接表
存储结构
1、顶点列表结构体
//结点列表
typedef struct NodeList
{char data;int length;EdgeNode* firstEdge;
}NodeList;
NodeList L[MAXSIZE];
2、邻接顶点结构体
//邻接结点
typedef struct EdgeNode
{int index;char data;int weight; //权重struct EdgeNode* next;
}EdgeNode, * pEdgeNode; //*pEdgeNode后面为创建二级指针
总代码
//网图的邻接表
//运用了二级指针:要直接修改地址需要用到二级指针
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;#define MAXSIZE 100
int length = 0;//邻接结点
typedef struct EdgeNode
{int index;char data;int weight; //权重struct EdgeNode* next;
}EdgeNode, * pEdgeNode; //*pEdgeNode后面为创建二级指针//结点列表
typedef struct NodeList
{char data;int length;EdgeNode* firstEdge;
}NodeList;
NodeList L[MAXSIZE];//输入并初始化
void Input_Init()
{int i = 0;char ch = ' ';printf("请输入需要创建的结点:\n");while (ch != '\n') //(这里其实用do while()会更好){scanf_s("%c", &ch);L[i].data = ch;L[i].firstEdge = NULL;i++;}length = i - 1; //包括了换行符printf("请分别输入这%d个结点的邻接结点的数量:\n", length);for (i = 0; i < length; i++){scanf("%d", &L[i].length);}
}//获取索引
int findIndex(char ch)
{int i = 0;for (i = 0; i < length; i++){if (ch == L[i].data)return i;}return -1;
}//创建列表
void CreateList()
{int i, j, weight;char ch = ' ';pEdgeNode* N = NULL; //----------------------二级指针--------------------//for (i = 0; i < length; i++){if (ch != '\n') //创建首{L[i].firstEdge = (EdgeNode*)malloc(sizeof(EdgeNode));//-----------------二级指针---------------//N = (pEdgeNode*)malloc(sizeof(pEdgeNode));N = &L[i].firstEdge;}printf("请分别输入%c结点的邻接结点和权重:\n", L[i].data);for (j = 0; j < L[i].length; j++){getchar();scanf("%c %d", &ch, &weight);if (ch == ' ') //空格不计{j--;continue;}//-----------------二级指针操作---------------//(*N)->index = findIndex(ch); //获取索引if ((*N)->index != -1) //有该元素{(*N)->data = ch; //赋值(*N)->weight = weight; //权重(*N)->next = (EdgeNode*)malloc(sizeof(EdgeNode)); //创建next指针N = &((*N)->next); //后移(指向next指针的地址)(注:next也为二级指针时不行,不知道为什么)}}(*N) = NULL; //----------地址置空,用到了二级指针----------//}
}//遍历
void Print()
{int i = 0, j;pEdgeNode* N;for (i = 0; i < length; i++){N = &L[i].firstEdge;printf("\n%c结点邻接结点:\n", L[i].data);while ((*N) != NULL){printf("%c权重:%d\n", (*N)->data, (*N)->weight);N = &((*N)->next);}}
}int main()
{Input_Init();CreateList();Print();return 0;
}
数据结构与算法(7-1)图的存储(邻接矩阵、邻接表)相关推荐
- 图的存储 邻接矩阵+邻接表+链式前向星
图的存储 - 邻接矩阵 在树的问题中,邻接矩阵是空间.时间的极大浪费. 假设树的结点个数为 N = 100000. 建立邻接矩阵需要空间为 1e5*1e5 但是由于只有 N - 1 条边,所以在邻接矩 ...
- 图的存储结构——邻接表法
图的存储结构--邻接表法 一.邻接表 由顶点表和边表构成,顶点表由顶点域(data)和指向第一条邻接边的指针(firstarc)构成,边表(邻接表)结点由邻接点域(adjvex)和指向下一条邻接边 ...
- 7.2图的存储结构(邻接表)
为什么要采用邻接表: 对于边数相对顶点较少的图,这种结构无疑是存储空间的极大浪费. 所以把数组和链表结合起来存储,这种方式在图结构中适用,称为邻接表(AdjacencyList) 邻接表的处理方法如下 ...
- 图的存储结构---邻接表
1. 邻接表(无向图) 对于边数相对顶点较少的图,可采取邻接表. 把数组与链表结合在一起来存储,这种方式在图结构也适用,称为邻接表(AdjacencyList). 2. 邻接表(有向图) 以每个顶点出 ...
- 【数据结构】图的存储结构—邻接表
目录 什么是邻接表? 邻接表:定义 邻接表:相关类 邻接表:基本操作 1)创建无向网 2)创建有向网 3)顶点定位 4)插入边 5)第一个邻接点 6)查询下一个邻接点 小试牛刀 对比邻接表与邻接矩阵
- 数据结构与算法10:图与图搜索
文章目录 图的概念与定义 图的表示与存储 图的表示 邻接矩阵 邻接表 图的应用 拓扑排序 最短路径 单源最短路径 Dijkstra 两点之间最短路径 Floyd 最小生成树 Kruskal Prim ...
- 【图】什么是图?无向图怎么存储?邻接表和邻接矩阵如何用代码存储图?
目录 一.概念 图是什么 各种图的定义 二.图的存储结构 邻接矩阵 邻接表 三.代码实现图的存储 1.无向图存储 2.邻接矩阵存储图 核心代码 完整代码 3.邻接表存储有向图(不含权重) 核心代码 完 ...
- 数据结构与算法学习笔记——图 C++实现
数据结构与算法学习笔记--图 C++实现 1 概念 2 图的表示方法 3 算法 3.1 拓扑排序 3.2 图的搜索算法 3.2.1 广度优先搜索(BFS) 3.2.2 深度优先搜索(DFS) 3.3 ...
- 数据结构与算法:17 图
17 图 知识结构: 1. 图的基本概念与术语 1.1 图的定义 图由顶点集和边集组成,记为G=(V,E)G=(V,E)G=(V,E). 顶点集:顶点的有穷非空集合,记为V(G)V(G)V(G). 边 ...
- 数据结构与算法思维导图(学习笔记)
版本 数据结构与算法思维导图V1.0 V1.0分享版本这个可以直接看,不需要下载. 说明 1.free 2.目前内容主要包含内容包含: 数据结构与算法思维导图 包含:线性表.顺序结构.链式结构,栈与队 ...
最新文章
- Clion 远程开发 配置
- AI一分钟 | 特朗普以国家安全为由否决博通收购高通;阿里发起时尚AI算法大赛
- java inflaterinputstream_java – Android InflaterInputStream是否与流行的ZLIB Windows库相同?...
- Python学习笔记-DNS处理模块dnspython
- GBin1分享的10个吸引眼球的jQuery插件
- GPU Gems1 - 23 景深技术综述
- php class使用方法,PHP调试类Krumo使用教程
- 公网ip和私网ip的区别_自带公网IP上阿里云
- 京东Q2营收同比增加26.2%,股价上涨超3%
- FFmpeg之mp4提取/h265(二十五)
- 1015 德才论 (25 分)—PAT (Basic Level) Practice (中文)
- 关于c++初始化原理与性能的讨论
- centos下安装Anaconda
- mysql海量数据查询/处理
- window10_vs2015安装教程
- python libusb_使用python开发usb的两种方式(windriver与pyusb)
- android发送短信验证码并自动获取验证码填充文本框
- 揭开期货反向跟单对冲的神秘面纱
- 陕西计算机在职研究生院校排名,陕西在职研究生哪个学校好上
- 中考考试的指令广播_考试语音指令系统