数据结构图的存储结构及基本操作
数据结构-chap7 (1)图的存储结构

V2
V4 G2图示
无向图:在图G中,若所有边是无向边,则称G为无向图。
有向图:在图G中,若所有边是有向边,则称G为有向图。
二、图的基本术语
有向完全图: n个顶点的有向图最大边数是n(n-1) 无向完全图: n个顶点的无向图最大边数是n(n-1)/2 1、邻接点及关联边
主要内容
知识点
– – – – 1.图的定义,概念、术语及基本操作。 2.图的存储结构,特别是邻接矩阵和邻接表。 3.图的深度优先遍历和宽度优先遍历。 4.图的应用(连通分量,最小生成树,拓扑排序,关键路经,最短 路经)。 1.基本概念中,完全图、连通分量、生成树和邻接点是重点。 2.建立图的各种存储结构的算法。 3.图的遍历算法及其应用。 4.通过遍历求出连通分量的个数,深(宽)度优先生成树。 5.最小生成树的生成过程。 6.拓扑排序的求法。关键路经的求法。 7.最短路径的手工模拟。
自测题 2
设无向图的顶点个数为n,则该图最多有( )条边。 A.n-1
B.n(n-1)/2
C.n(n+1)/2 D.0 E.N2 【清华大学1998一.5(分)】
自测题 3
一个有n个结点的图,最少有( )个连通分量,最多有( )个 连通分量。
A. 0
B.1 C.n-1 D.n 【北京邮电大学 2000 二.5 (20/8分)】
0
V1 e1 V3 V4 V5 V2 1 0 1 0 1
否则
0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 V1 V2 0 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0
数据结构试验报告-图的基本操作

中原工学院《数据结构》实验报告学院:计算机学院专业:计算机科学与技术班级:计科112姓名:康岩岩学号:201100814220 指导老师:高艳霞2012-11-22实验五图的基本操作一、实验目的1、使学生可以巩固所学的有关图的基本知识。
2、熟练掌握图的存储结构。
3、熟练掌握图的两种遍历算法。
二、实验内容[问题描述]对给定图,实现图的深度优先遍历和广度优先遍历。
[基本要求]以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。
以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。
【测试数据】由学生依据软件工程的测试技术自己确定。
三、实验前的准备工作1、掌握图的相关概念。
2、掌握图的逻辑结构和存储结构。
3、掌握图的两种遍历算法的实现。
四、实验报告要求1、实验报告要按照实验报告格式规范书写。
2、实验上要写出多批测试数据的运行结果。
3、结合运行结果,对程序进行分析。
【设计思路】【代码整理】#include "stdafx.h"#include <iostream>#include <malloc.h>using namespace std;typedef int Status;#define OK 1#define ERROR 0#define OVERFLOW -1#define MAX_SIZE 20typedef enum{DG,DN,UDG,UDN}Kind;typedef struct ArcNode{int adjvex; //顶点位置struct ArcNode *nextarc; //下一条弧int *info; //弧信息};typedef struct{char info[10]; //顶点信息ArcNode *fistarc; //指向第一条弧}VNode,AdjList[MAX_SIZE];typedef struct{AdjList vertices;int vexnum,arcnum; //顶点数,弧数int kind; //图的种类,此为无向图}ALGraph;//这是队列的节点,仅用于广度优先搜索typedef struct Node{int num;struct Node* next;};//队列的头和尾typedef struct{Node * front;Node *rear;}PreBit;int LocateV ex(ALGraph G,char info[]);//定位顶点的位置Status addArcNode(ALGraph &G,int adjvex); //图中加入弧Status CreatGraph(ALGraph&G);//创建图的邻接表Status DFSTraverse(ALGraph G);//深度优先搜索Status BFSTraverse(ALGraph G);//广度优先搜索Status DFS(ALGraph G,int v);//深度优先搜索中的数据读取函数,用于递归bool visited[MAX_SIZE]; // 访问标志数组//初始化队列Status init_q(PreBit&P_B){P_B.front=P_B.rear=(Node*)malloc(sizeof(Node));if(!P_B.front){exit(OVERFLOW);}P_B.front->next=NULL;}//将数据入队Status en_q(PreBit & P_B,int num){Node *p=(Node*)malloc(sizeof(Node));if(!p){exit(OVERFLOW);}p->num=num;p->next=NULL;P_B.rear->next=p;P_B.rear=p;return OK;}//出队Status de_q(PreBit & P_B){if(P_B.front==P_B.rear){return ERROR;}Node* p=P_B.front->next;P_B.front->next=p->next;if(P_B.rear==p){P_B.rear=P_B.front;}free(p);return OK;}Status CreatGraph(ALGraph&G){cout<<"请输入顶点数目和弧数目"<<endl;cin>>G.vexnum>>G.arcnum;//依次输入顶点信息for(int i=0;i<G.vexnum;i++){cout<<"请输入顶点名称"<<endl;cin>>G.vertices[i].info;G.vertices[i].fistarc=NULL;}//依次输入弧信息for(int k=1;k<=G.arcnum;k++){char v1[10],v2[10]; //用于表示顶点名称的字符数组int i,j; //表示两个顶点的位置BACK: //返回点cout<<"请输入第"<<k<<"条弧的两个顶点"<<endl;cin>>v1>>v2;i=LocateV ex(G,v1); //得到顶点v1的位置j=LocateV ex(G,v2); //得到顶点v2的位置if(i==-1||j==-1){ //头信息不存在则返回重输cout<<"不存在该节点!"<<endl;goto BACK; //跳到BACK 返回点}addArcNode(G,i); //将弧的顶点信息插入表中addArcNode(G,j);}return OK;}//倒序插入弧的顶点信息Status addArcNode(ALGraph &G,int adjvex){ArcNode *p; //弧节点指针p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=adjvex;p->nextarc=G.vertices[adjvex].fistarc;//指向头结点的第一条弧G.vertices[adjvex].fistarc=p; //头结点的第一条弧指向p,即将p作为头结点的第一条弧return OK;}//定位顶点的位置int LocateV ex(ALGraph G,char info[]){for(int i=0;i<G.vexnum;i++){if(strcmp(G.vertices[i].info,info)==0){ //头结点名称与传入的信息相等,证明该头节点存在return i; //此时返回位置}}return -1;}//深度优先搜索Status DFSTraverse(ALGraph G){for(int v=0;v<G.vexnum;v++){visited[v]=false;}char v1[10];int i;BACK:cout<<"请输入首先访问的顶点"<<endl;cin>>v1;i=LocateV ex(G,v1);if(i==-1){cout<<"不存在该节点!"<<endl;goto BACK;}DFS(G,i);return OK;}//深度优先搜索递归访问图Status DFS(ALGraph G,int v){visited[v]=true;cout<<G.vertices[v].info<<" ";//输出信息ArcNode *p;p=G.vertices[v].fistarc; //向头节点第一条while(p) //当弧存在{if(!visited[p->adjvex]){DFS(G,p->adjvex); //递归读取}p=p->nextarc;}return OK;}//广度优先搜索Status BFSTraverse(ALGraph G){for(int v=0;v<G.vexnum;v++){visited[v]=false;}char v1[10];int v;BACK:cout<<"请输入首先访问的顶点"<<endl;cin>>v1;v=LocateV ex(G,v1);if(v==-1){cout<<"不存在该节点!"<<endl;goto BACK;}PreBit P_B;init_q(P_B);ArcNode *p;visited[v]=true;cout<<G.vertices[v].info<<" ";//输出信息en_q(P_B,v); //将头位置v入队while(P_B.front!=P_B.rear){//当队列不为空时,对其进行访问int w=P_B.front->next->num;//读出顶点位置de_q(P_B);//顶点已经访问过,将其出队列p=G.vertices[w].fistarc;//得到与顶点相关的第一条弧while(p){if(!visited[p->adjvex]){en_q(P_B,p->adjvex);//将弧入队,但不读取,只是将其放在队尾}p=p->nextarc;}}return OK;}int _tmain(int argc, _TCHAR* argv[]){ALGraph G;CreatGraph(G);cout<<"深度优先搜索图:"<<endl;DFSTraverse(G);cout<<endl;cout<<"广度优先搜索图:"<<endl;BFSTraverse(G);cout<<endl;system("pause");return 0;}。
数据结构图知识点总结高中

数据结构图知识点总结高中一、线性结构1. 线性表线性表是数据结构中最基本的一种结构,它是由零个或多个数据元素构成的有限序列。
其中每个数据元素都只有一个前驱元素和一个后继元素,除了第一个和最后一个元素外,其他元素都有且仅有一个前驱和一个后继。
线性表有两种基本的存储结构,分别是顺序存储结构和链式存储结构。
顺序存储结构是利用一组地址连续的存储单元来存放线性表的数据元素,而链式存储结构是通过指针来表示数据元素之间的逻辑关系。
2. 栈栈是一种特殊的线性表,它只能在表的一端进行插入和删除操作。
栈有一个被称为栈顶的元素,只能在栈顶进行插入和删除操作。
栈有两种经典的存储结构,分别是顺序栈和链式栈。
顺序栈是利用数组来实现栈的存储和操作,而链式栈则是利用链表来实现栈的存储和操作。
3. 队列队列也是一种特殊的线性表,它只能在表的两端进行插入和删除操作。
队列有一个被称为队头和队尾的元素,只能在队头进行删除操作,只能在队尾进行插入操作。
队列也有两种经典的存储结构,分别是顺序队列和链式队列。
顺序队列是利用数组来实现队列的存储和操作,而链式队列则是利用链表来实现队列的存储和操作。
4. 串串是线性表的一种特殊形式,它是由零个或多个字符构成的有限序列。
串的存储结构有两种常见的形式,分别是顺序存储结构和链式存储结构。
顺序存储结构是利用数组来存储串的字符序列,而链式存储结构是利用链表来存储串的字符序列。
二、非线性结构1. 树树是一种非线性结构,它是由n (n ≥ 1) 个节点组成的有限集合,这些节点之间存在着明确的层次关系。
树的存储结构通常有两种形式,分别是双亲表示法和孩子表示法。
双亲表示法通过数组来存储树的节点和节点之间的关系,而孩子表示法则通过链表来存储树的节点和节点之间的关系。
树有许多种特殊形式,如二叉树、平衡二叉树、多路查找树等。
其中,二叉树是一种特殊的树,它的每个节点最多有两个子节点,这两个子节点被称为左子树和右子树。
2. 图图是一种非线性结构,它是由一组顶点和一组边组成的数据结构。
数据结构图

所以:对于点多边少的稀疏图来说,采用邻接表 结构使得算法在时间效 率上大大提高。
16
3/12
广度优先搜索(Breadth First Search,简称BFS ) BFS类似于树的层序遍历; 用一个数组用于标志已访问与否,还需要一个工作队列。
【例】一个无向图的BFS
8
6
CD
4
7
HG
BA
邻接多重表(Adjacency Multilist)
9
边表
• 在某些应用中,有时主要考察图中边的权值以及所依附的 两个顶点,即图的结构主要由边来表示,称为边表存储结 构。
• 边表结构采用顺序存储,用2个一维数组构成,一个存储 顶点信息,一个存储边的信息。边数组的每个元素由三部 分组成:
– 边的起点下标 – 边的终点下标 – 边的权值
1
A [i][
j]
0
如果 (vi , v j ) 或 vi , v j G的边 其它
无权图的邻接矩阵表示示例
V1
V2
V0
3
V3
4 12/15
带权图的邻接矩阵的定义
A [i][ j] wij
如果 (vi , vj ) 或 vi , v j G的边 其它
带图权的图邻的接邻矩接阵矩表阵示表示示例示[例例6.9]
1
第一部分 图的定义和术语
2
图的定义
“图” G可以表示为两个集合:G =(V, E)。每条 边是一个顶点对(v, w) E ,并且 v, w V。
通常:用 |V| 表示顶点的数量(|V| ≥ 1), 用 |E| 表示边的数量(|E| ≥ 0)。
(1) 无向图(完全有向图边数与顶点数之间的 关系) (2) 有向图(完全有向图弧数与顶点数之间的 关系) (3) 简单图:没有重边和自回路的图 (4) 邻接 (5) 路径,路径长度 (6) 无环(有向)图:没有任何回路的(有向)图 (7) 度,入度,出度 (8) 无向图的顶点连通、连通图、连通分量 (9) 有向图的顶点强连通,强连通图、连通分量
数据结构-图及其存储结构

for (j=0;j<G.vexnum;+ +j ) adj Info G.arcs[i][j]={∞,NULL}; //Arccell的形式为: for (k=0;k<G.arcnum;+ +i ) { //二维数组存放各边上的信息 scanf(v1,v2,w); i=locatevex(G,v1); j=locatevex(G,v2); //求顶点v1,v2在图中的位置 G.arcs[i][j].adj=w; G.arcs[j][i].adj=w; //无向网的邻接矩阵是对称的 if (IncInfo) Input (*G.arcs[i][j].info); //将弧上的信息存储在指针info
case UDN: return CreateUDN(G);
default : return ERROR; }//CreateGraph
二、存储结构
2.数组表示法前提下图的输入
*以无向网为例,即当用户输入图的类型标志为UDN时,有:
Status CreateUDN(MGraph &G){ scanf(G.vexnum,G.arcnum,IncInfo); //IncInfo 为0时表示各弧
v2 6 5
v1 5 1 5 v3 3 6 4 2 v4
一个连通无向图的生成树是该图的一个连通分量,它 包含有该图的所有n个顶点以及连接这n个顶点的(n-1) 条边。 边或弧上带权值的图称为带权图或网(分为无向网和 有向网)。 一个无向图的所有生成树中,边上的权值之和最小的 生成树称为该图的最小生成树或最小代价生成树。
《数据结构之图》相关知识点总结

第5章图●图的定义①图由顶点集V和边集E组成,记为G=(V,E),V(G)是图G中顶点的有穷非空集合,E(G)是图G中顶点之间变得关系集合,|V|表示顶点个数,也称图的阶,|E|表示边数(线性表和树都可以是空的,但图可以只有一个顶点没有边)②有向图:弧是顶点的有序对,记为<v,w>,v,w是顶点,v是弧尾,w是弧头,从顶点v到顶点w的弧。
无向图:边是顶点的无序对,记为(v,w)③简单图:一个图满足:不存在重复边;不存在顶点到自身的边。
多重图相对于简单图定义④完全图:无向图中,任意两顶点之间存在边,称为完全无向图。
N个顶点的无向完全图有n(n-1)/2条边。
在有向图中,任意两顶点之间存在方向相反的两条弧,称为有向完全图,N 个顶点的有向完全图有n(n-1)条边。
⑤连通图:在无向图中任意两顶点都是连通的。
无向图中的极大连通子图称为连通分量。
极大要求连通子图包含其所有的边和顶点,极小连通子图既要保持图连通,又要保持边数最少⑥在有向图中任意两顶点v,w,存在从顶点v到顶点w和从顶点w到顶点v两条路径,这种图称为强连通图。
有向图的极大强连通子图称为有向图的强连通分量。
⑦生成树:①包含图中所有顶点n,②生成树有n-1条边, ③任意两点连通。
对生成树而言,砍去一条边变成非连通图,加上一条边形成一个回路。
在非连通图中,连通分量的生成树构成了非连通图的生成森林。
⑧顶点的度:以该顶点为端点的边的数目。
无向图的全部顶点的度之和等于边数的两倍。
有向图的度等于出度和入度之和,入度是以该顶点为终点的有向边的数目,出度是以该顶点为起点的有向边的数目。
有向图的全部顶点的入度之和和出度之和相等且等于边数。
⑨图中每条边可以标上具有某种含义的数值,该数值称为边的权值。
带有权值的图称为网。
○10对于无向图G=(V, {E}),如果边(v,v’)∈E,则称顶点v,v’互为邻接点,即v,v’相邻接。
边(v,v’)依附于顶点v 和v’,或者说边(v, v’)与顶点v 和v’相关联。
数据结构图结构(动态PPT)课件

结合实际问题
将数据结构图与实际问题相结合,通过分析问题的本质和 规律,选择合适的数据结构和算法进行求解。
创新应用方式
在传统的数据结构图应用基础上,探索新的应用方式和方 法,如基于数据结构图的机器学习模型、数据结构图在社 交网络分析中的应用等。
跨学科融合
将数据结构图与其他学科领域进行融合,如物理学、化学 、生物学等,通过借鉴其他学科的理论和方法,创新数据 结构图的应用场景和解决方案。
包括无向图、有向图、权 重图、邻接矩阵、邻接表 等。
图的遍历方法
深度优先搜索(DFS)和 广度优先搜索(BFS)的 原理和实现。
非线性数据结构图应用案例
树的应用案例
包括二叉搜索树、堆、哈夫曼树等在实际问题中的应用,如排序、优先队列、 编码等。
图的应用案例
包括最短路径问题(Dijkstra算法、Floyd算法)、最小生成树问题(Prim算法 、Kruskal算法)以及网络流问题等在实际问题中的应用,如交通网络规划、电 路设计等。
根据实际需求,选择适合的最小生 成树算法,如Prim算法、Kruskal算
法等。
B
C
D
可视化呈现结果
将算法的运行过程和结果以图形化的方式 呈现出来,方便用户直观地理解和掌握最 小生成树算法的原理和实现过程。
实现算法逻辑
编写代码实现最小生成树算法的逻辑,包 括节点的选择、边的添加和权重的计算等 。
拓展思考:如何创新应用数据结构图解决问题
作用
帮助理解复杂数据结构的组成和 关系,提高数据处理的效率。
常见类型及特点
01
02
03
04
线性数据结构图
元素之间一对一关系,如数组 、链表等。
树形数据结构图
数据结构的三大概念逻辑结构、存储结构和运算

数据结构的三大概念逻辑结构、存储结构和运算数据结构的三大概念:逻辑结构、存储结构和运算数据结构是计算机科学中非常重要的一个概念,它是指数据元素之间的关系以及对这些数据元素进行操作的方法。
在数据结构中,有三个核心概念,分别是逻辑结构、存储结构和运算。
这三个概念相互联系、相互作用,共同构成了数据结构的基本框架。
下面将分别对这三个概念进行详细介绍。
逻辑结构逻辑结构是指数据元素之间的逻辑关系,它独立于数据元素的存储结构。
在数据结构中,常见的逻辑结构包括线性结构、树形结构和图形结构。
1. 线性结构线性结构是最简单、最基本的逻辑结构,数据元素之间是一对一的关系。
线性结构包括线性表、栈、队列等。
其中,线性表是最为常见的线性结构,它包括顺序表和链表两种存储结构。
顺序表中的数据元素在内存中是连续存储的,而链表中的数据元素在内存中是不连续存储的,通过指针来连接各个节点。
2. 树形结构树形结构是一种重要的非线性结构,它包括二叉树、二叉搜索树、平衡二叉树等。
在树形结构中,每个节点可以有零个或多个子节点,节点之间通过边相连。
树形结构常用于表示具有层次关系的数据,如文件系统、组织结构等。
3. 图形结构图形结构是最为复杂的逻辑结构,它包括有向图和无向图。
在图形结构中,节点之间的关系是任意的,可以是一对一、一对多或多对多的关系。
图形结构常用于描述网络、社交关系等复杂系统。
存储结构存储结构是指数据结构在计算机内存中的表示方式,它决定了数据元素在内存中的存储位置以及数据元素之间的物理关系。
常见的存储结构包括顺序存储结构和链式存储结构。
1. 顺序存储结构顺序存储结构是将数据元素存储在一块连续的内存空间中,数据元素之间的物理关系与其逻辑关系一致。
顺序存储结构适合于对数据元素的随机访问,但插入和删除操作效率较低。
2. 链式存储结构链式存储结构是通过指针将数据元素存储在不连续的内存空间中,数据元素之间通过指针相连。
链式存储结构适合于频繁的插入和删除操作,但访问效率较低。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.实验目的通过上机实验进一步掌握图的存储结构及基本操作的实现。
2.实验内容与要求要求:⑴能根据输入的顶点、边/弧的信息建立图;⑵实现图中顶点、边/弧的插入、删除;⑶实现对该图的深度优先遍历;⑷实现对该图的广度优先遍历。
备注:单号基于邻接矩阵,双号基于邻接表存储结构实现上述操作。
3.数据结构设计逻辑结构:图状结构存储结构:顺序存储结构、链式存储结构4.算法设计#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAX_VERTEX_NUM 20 typedef struct ArcNode{int adjvex;struct ArcNode *nextarc; }ArcNode;typedef struct VNode{char data[2]; //顶点就设置和书上V1等等一样吧ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM]; typedef struct{AdjList vertices;int vexnum,arcnum;}ALGraph;typedef struct{int data[MAX_VERTEX_NUM+10];int front;int rear;}queue;int visited[MAX_VERTEX_NUM]; queue q;int main(){ALGraph G;int CreateUDG(ALGraph &G);int DeleteUDG(ALGraph &G);int InsertUDG(ALGraph &G);void BFSTraverse(ALGraph G, int (*Visit)(ALGraph G,ArcNode v));int PrintElement(ALGraph G,ArcNode v);void menu();void depthfirstsearch(ALGraph *g,int vi);void travel(ALGraph *g);void breadfirstsearch(ALGraph *g);int i;G.arcnum = G.vexnum = 0;while(1){menu();do{printf ( "请输入要进行的操作\n" );scanf ("%d",&i);if (i<1||i>6)printf("错误数字,请重新输入\n");}while (i<1||i>6);switch (i){case 1: CreateUDG(G);system("pause"); system("cls"); break;case 2: DeleteUDG(G); system("pause"); system("cls"); break;case 3: InsertUDG(G); system("pause"); system("cls"); break;case 4: travel(&G); system("pause"); system("cls"); break;case 5: breadfirstsearch(&G); system("pause"); system("cls"); break;case 6: exit(0); break;}}return 1;}void enterqueue(int v){q.data[q.rear]=v;q.rear++;}int deletequeue(){int t;t=q.data[q.front];q.front++;return(t);}int empty(){if(q.front==q.rear)return 1;return 0;}int LocateVex(ALGraph G,char node[2]) {int i;for(i = 0 ; i < G.vexnum ; i++){if(strcmp(G.vertices[i].data,node)= =0)return i;}return -1;}int CreateUDG(ALGraph &G){int LocateVex(ALGraph G,char node[2]);void PrintUDG(ALGraph G);int i,j,k;char node1[2],node2[2];ArcNode *p,*q;printf("请输入顶点数和弧数\n");printf("例如:5,6\n");scanf("%d,%d",&G.vexnum,&G.arc num);printf("请输入各顶点\n");for(i = 0 ; i < G.vexnum ; i++){printf("第%d个\n",i+1);scanf("%s",&G.vertices[i]);G.vertices[i].firstarc = NULL;}//这里开始构造边printf("请输入边的信息\n");printf("例如:v1 v2\n");for(i = 0 ; i < G.arcnum ; i++){printf("第%d条边\n",i+1);scanf("%s %s",&node1,&node2);j = LocateVex(G,node1);k = LocateVex(G,node2);p = (ArcNode *)malloc(sizeof(ArcNode));q = (ArcNode *)malloc(sizeof(ArcNode));p->adjvex = k;q->adjvex = j;p->nextarc = G.vertices[j].firstarc;G.vertices[j].firstarc = p;q->nextarc = G.vertices[k].firstarc;G.vertices[k].firstarc = q;}PrintUDG(G);return 1;}int DeleteUDG(ALGraph &G){int i,j;ArcNode *p,*q;char node[2];int LocateVex(ALGraph G,char node[2]);void PrintUDG(ALGraph G);if(G.arcnum == 0){printf("请先生成图\n");return 0;}printf("请输入要删除的节点\n");scanf("%s",&node);i = LocateVex(G,node);if(i == -1){printf("无此节点\n");return 0;}else{G.vexnum--;if((p = q = G.vertices[i].firstarc) != NULL){G.arcnum--;p = p->nextarc;G.vertices[i].firstarc = p;free(q);q = p;while(p != NULL){G.arcnum--;p = p->nextarc;G.vertices[i].firstarc = p;free(q);q = p;}}for(j = 0 ; j < G.vexnum ; j++ ){if(j >= i){strcpy(G.vertices[j].data , G.vertices[j+1].data);G.vertices[j].firstarc = G.vertices[j+1].firstarc;}if(G.vertices[j].firstarc->nextarc != NULL){p = G.vertices[j].firstarc;q = p->nextarc;if(p->adjvex == i){G.vertices[j].firstarc = q;p = q;q = q->nextarc;continue;}else if(p->adjvex > i)p->adjvex--;while(q != NULL){if(q->adjvex == i){p->nextarc = q->nextarc;free(q);q = p->nextarc;}elseif(q->adjvex > i)q->adjvex--;else{p = p->nextarc;q = q->nextarc;}}}elseif( (G.vertices[j].firstarc->nextarc == NULL) && (G.vertices[j].firstarc != NULL) )if( G.vertices[j].firstarc->adjvex == i ){G.vertices[j].firstarc = NULL;}}}PrintUDG(G);return 1;}int InsertUDG(ALGraph &G){//默认一次插入一个节点吧,不然太麻烦int i,j,k,l;char node1[2],node2[2];ArcNode *p,*q;int LocateVex(ALGraph G,char node[2]);void PrintUDG(ALGraph G);if(G.arcnum == 0){printf("请先生成图\n");return 0;}printf("请输入插入节点的名称\n");printf("WARNING:绝不可以和之前的节点重名!\n");scanf("%s",&G.vertices[G.vexnum]. data);G.vertices[G.vexnum].firstarc = NULL;printf("请输入需要插入的边的数目\n");scanf("%d",&i);G.arcnum += i;G.vexnum++;printf("请输入边的信息\n");printf("例如:v6 v2\n");printf("WARNING:一定要包含刚加入的节点名称!\n");for(j = 0 ; j < i ; j++){printf("第%d条边\n",j+1);scanf("%s %s",&node1,&node2);l = LocateVex(G,node1);k = LocateVex(G,node2);p = (ArcNode *)malloc(sizeof(ArcNode));q = (ArcNode *)malloc(sizeof(ArcNode));p->adjvex = k;q->adjvex = l;p->nextarc = G.vertices[l].firstarc;G.vertices[l].firstarc = p;q->nextarc = G.vertices[k].firstarc;G.vertices[k].firstarc = q;}PrintUDG(G);return 1;}void depthfirstsearch(ALGraph *g,int vi){ArcNode *rear;printf("%s\t",g->vertices[vi].data);visited[vi]=1;rear=g->vertices[vi].firstarc;while((rear!=NULL)&&(!visited[rear->a djvex])){depthfirstsearch(g,rear->adjvex);rear=rear->nextarc;}}void travel(ALGraph *g){int v;for(v=0;v<g->vexnum;v++)if(!visited[v])depthfirstsearch(g,v); }void breadfirstsearch(ALGraph *g) {int v,t,i;ArcNode *rear;for(i = 0 ; i <g->vexnum ; i++) visited[i] = 0;for(v=0;v<g->vexnum;v++){if(!visited[v]){printf("%s",g->vertices[v].data);visited[v]=1;enterqueue(v);}while(!empty()){t=deletequeue();rear=g->vertices[t].firstarc;while((rear!=NULL)&&(!visited[rear->a djvex])){printf("%s\t",g->vertices[rear->adjvex]. data);visited[rear->adjvex]=1;enterqueue(rear->adjvex);rear=rear->nextarc;}}}}void menu(){printf("********************************* ************\n");printf("* 作者:Dick *\n");printf("* 信计1001 xxxxxxxxxx *\n");printf("*********************MENU***** ***************\n");printf("1 建立无向图\n");printf("2 删除图中节点\n");printf("3 插入节点\n");printf("4 深度优先遍历图\n");printf("5 广度优先遍历图\n");printf("6 退出程序\n");}void PrintUDG(ALGraph G){int i;ArcNode *p;for(i = 0 ; i < G.vexnum ; i++){if(G.vertices[i].firstarc != NULL){printf("与节点%s相邻的节点为:\n",G.vertices[i].data);p = G.vertices[i].firstarc;while(p != NULL){printf("%s\t",G.vertices[p->adjvex]. data);p = p->nextarc;}printf("\n");-------------精选文档-----------------可编辑}else printf("无与节点%s 相邻的节点\n",G.vertices[i].data); }} 5. 测试结果图一:菜单项图三:插入节点图一:菜单项图二:建立图图二:建立图遍历图。