问题描述 :

目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT)。

内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)

(2)设计并实现一个算法,在已存在的图中返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1。图的存储结构采用邻接表。将其加入到ADT中。

注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)

参考函数原型:

//返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回false

template<class TypeOfVer, class TypeOfEdge>

int adjlist_graph<TypeOfVer, TypeOfEdge>::GetNextAdjVex(int u, int v, int &w);

图的邻接表模板类原型参考如下:

/* 边表的结点定义 */

template<class TypeOfEdge>

struct edgeNode

{

int data;

TypeOfEdge weight;

edgeNode<TypeOfEdge> *next;

edgeNode(const int &d, edgeNode<TypeOfEdge> *ptr = NULL) //构造函数,用于构造其他结点(无权图)

//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面

{

next = ptr;

data = d;

}

edgeNode(const int &d, const TypeOfEdge &w, edgeNode<TypeOfEdge> *ptr = NULL) //构造函数,用于构造其他结点(带权图)

//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面

{

next = ptr;

data = d;

weight = w;

}

int getData(){ return data;}  //取得结点的序号(顶点集)

TypeOfEdge getWeight(){ return weight;}  //取得边集中对应边的权值

void SetLink( edgeNode<TypeOfEdge> *link ){ next = link; }  //修改结点的next域

void SetData( int value ){ data = value; }   //修改结点的序号(顶点集)

void SetWeight(TypeOfEdge value ){ weight = value; }   //修改边集中对应边的权值

};

//图的邻接表类

template<class TypeOfVer, class TypeOfEdge>

struct verNode

{

TypeOfVer ver;

edgeNode<TypeOfEdge> *head;

verNode(edgeNode<TypeOfEdge> *h = NULL){head = h;}

TypeOfVer getVer(){ return ver;}  //取得结点值(顶点集)

edgeNode<TypeOfEdge> *getHead(){ return head;}  //取得对应的边表的头指针

void setVer(TypeOfVer value){ ver = value;}  //设置结点值(顶点集)

void setHead(edgeNode<TypeOfEdge> *value){ head = value;}  //设置对应的边表的头指针

};

template <class TypeOfVer, class TypeOfEdge>

class adjlist_graph{

private:

int Vers;           //顶点数

int Edges;          //边数

verNode<TypeOfVer,TypeOfEdge> *verList;

string GraphKind;     //图的种类标志

bool Delete_Edge( int u, int v );

bool DFS(int u, int &num, int visited[]); //DFS遍历(递归部分)

public:

adjlist_graph( const string &kd, int vSize, const TypeOfVer d[]); //构造函数构造一个只有结点没有边的图。

adjlist_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e); 构造函数构造一个无权图。5个参数的含义:图的类型、结点数、边数、结点集和边集

adjlist_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e, const TypeOfEdge w[]); //构造函数构造一个有权图。

bool GraphisEmpty() { return Vers == 0; }  //判断图空否

string GetGraphKind(){ return GraphKind; }

bool GetVer(int u, TypeOfVer &data); //取得G中指定顶点的值

int GetFirstAdjVex(int u, int &v); //返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1

int GetNextAdjVex(int u, int v, int &w); //返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回false

bool PutVer(int u, TypeOfVer data); //对G中指定顶点赋值

bool InsertVer(const TypeOfVer &data); //往G中添加一个顶点

int LocateVer(TypeOfVer data); //返回G中指定顶点的位置

bool ExistEdge(int u, int v);

bool PrintVer();  //输出顶点集

bool PrintAdjList();  //输出邻接矩阵

int GetVerNum(){ return Vers;}    //取得当前顶点数

int GetEdgeNum(){ return Edges;}  //取得当前边数

bool Insert_Edge(int u, int v); //无权图插入一条边

bool Insert_Edge(int u, int v, TypeOfEdge w); //有权图插入一条边

bool DeleteVer(const TypeOfVer &data); //往G中删除一个顶点

bool DeleteEdge( int u, int v ); //删除边 (外壳:有向(删除1条边), 无向(删除2条边))

void DFS_Traverse(int u); //DFS遍历(外壳部分)

void BFS_Traverse(int u); //BFS遍历

~adjlist_graph(); //析构函数

};

输入说明 :

建图的输入数据格式参见建图的算法说明。

第一行:图的类型

第二行:结点数

第三行:结点集

第四行:边数

第五行:边集

第六行:指定顶点的位序

第七行:参照顶点的位序

输出说明 :

第一行:顶点集

第二行:邻接表

空行

第三行:下一个邻接顶点的位序(如无邻接顶点,则输出-1)

输入范例 :

DG
6
A B C D E F
6
0 1
0 2
0 3
1 4
2 4
3 5
0
3

输出范例 :

A B C D E F
A->3->2->1
B->4
C->4
D->5
E
F

2

解题代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <sstream>
#include <stack>
#include <map>
#include <ctime>
#include <array>
#include <set>
#include <list>
using namespace std;
//边的定义
template<class TypeOfEdge>
struct Edge_pair
{int point = 0;TypeOfEdge length = 0;//=================
};
//顶点的定义
template<class TypeOfVer, class TypeOfEdge>
struct verNode
{TypeOfVer ver_data;list<Edge_pair<TypeOfEdge> > group;//构造函数,默认会讲头指针设为空.verNode(){group.clear();ver_data = 0;}//取得结点值(顶点) 估计是为了安全吧???TypeOfVer getVer(){return ver_data;}//取得对应的边表list<Edge_pair<TypeOfEdge> > getHead(){return group;}//设置结点值(顶点集) 估计是为了安全吧???void setdata(TypeOfVer value){ver_data = value;return;}//=====================================================void creat_Point(int new_point, TypeOfEdge new_length){Edge_pair<TypeOfEdge> Next_p;Next_p.point = new_point;Next_p.length = new_length;group.insert(group.begin(), Next_p);return;}//删除指定位置顶点void del_Point(int n){return;}
};template <class TypeOfVer, class TypeOfEdge>//顶点元素类型,边权值类型
class adjlist_graph {
private:int Vers;//顶点数 int Edges;//边数 vector<verNode<TypeOfVer, TypeOfEdge> >ver;//顶点存储string GraphKind;//图的种类标志 bool have_dir = false, have_w = false;//图类型参数//======================================================================bool Delete_Edge(int u, int v)//删除一条边{return false;}bool DFS(int u, int& num, int visited[])//DFS遍历(递归部分){return false;}public://一个空的构造函数adjlist_graph(){Edges = 0;Vers = 0;}//假的析构函数 ~adjlist_graph(){;//你电脑内存就640K吗?}//判断图空否bool GraphisEmpty(){return Vers == 0;}//获取图的类型string GetGraphKind(){return GraphKind;}//取得当前顶点数 int GetVerNum(){return Vers;}//取得当前边数 int GetEdgeNum(){return Edges;}//自动建立临接表bool Auto_build(void){//DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)/*第一行:图的类型  DN UDN第二行:结点数第三行:结点集第四行:无边标记第五行:边数第六行:边集第七行:权集*//*第一行:图的类型  DG UDG第二行:结点数第三行:结点集第四行:边数第五行:边集*/cin >> GraphKind;//图的类型 cin >> Vers;//结点数ver.resize(Vers);//开辟节点空间for (int i = 0; i < Vers; i++)//结点集{TypeOfVer now;cin >> now;ver[i].setdata(now);}cin >> Edges;//边数vector<int> x_p, y_p, w_p;for (int i = 0; i < Edges; i++){int c_x, c_y;cin >> c_x >> c_y;x_p.push_back(c_x);y_p.push_back(c_y);}//图的类型识别if (GraphKind == "DG")//DG(有向图)have_dir = true, have_w = false;if (GraphKind == "DN")//DN(有向网)have_dir = true, have_w = true;if (GraphKind == "UDG")//UDG(无向图)have_dir = false, have_w = false;if (GraphKind == "UDN")//UDN(无向网)have_dir = false, have_w = true;if (have_w)for (int i = 0; i < Edges; i++){int c_w;cin >> c_w;w_p.push_back(c_w);}for (int i = 0; i < Edges; i++){if (have_dir)if (have_w)ver[x_p[i]].creat_Point(y_p[i], w_p[i]);elsever[x_p[i]].creat_Point(y_p[i], 0);elseif (have_w)ver[x_p[i]].creat_Point(y_p[i], w_p[i]), ver[y_p[i]].creat_Point(x_p[i], w_p[i]);elsever[x_p[i]].creat_Point(y_p[i], 0), ver[y_p[i]].creat_Point(x_p[i], 0);}return 1;}//取得G顶点的组vector<TypeOfVer> GetVer(void){vector<TypeOfVer> head_group;for (int i = 0; i < Vers; i++){head_group.push_back(ver[i].getVer());}return head_group;}//输出邻接表 bool Print_photo(){int i;for (i = 0; i < Vers; i++){cout << ver[i].getVer();if (ver[i].group.size() != 0)cout << "->";else{cout << endl;continue;}vector<Edge_pair<TypeOfEdge> > out_lis;out_lis.clear();for (auto j = ver[i].group.begin(); j != ver[i].group.end(); j++){out_lis.push_back(*j);}int j;for (j = 0; j < out_lis.size() - 1; j++)if (have_w)cout << out_lis[j].point << "(" << out_lis[j].length << ")" << "->";elsecout << out_lis[j].point << "->";if (have_w)cout << out_lis[j].point << "(" << out_lis[j].length << ")" << endl;elsecout << out_lis[j].point << endl;}return 1;}//往G中添加一个顶点 bool InsertVer(const TypeOfVer& data){verNode<TypeOfVer, TypeOfEdge> new_e;new_e.setdata(data);ver.push_back(new_e);Vers++;return true;}//寻找顶点位置int Look_Ver(const TypeOfVer& data){int i;for (i = 0; i < Vers; i++)if (ver[i].ver_data == data)return i;return -1;}//删除一个顶点bool del_Point(int place){int need_del = 0;if (!(0 <= place && place < Vers))return false;int i;for (i = 0; i < Vers; i++){for (auto j = ver[i].group.begin(); j != ver[i].group.end(); j++){if (j->point == place){need_del++;ver[i].group.erase(j);break;}}for (auto j = ver[i].group.begin(); j != ver[i].group.end(); j++){if (j->point > place)j->point--;}}need_del += ver[place].group.size();ver.erase(ver.begin() + place);Vers--;if (have_dir)Edges -= need_del;elseEdges -= (need_del / 2);return true;}//无权图插入一条边bool Insert_Edge(int u, int v){if (!(0 <= u && u < Vers))return false;if (!(0 <= v && v < Vers))return false;for (auto i = ver[u].group.begin(); i != ver[u].group.end(); i++){if (i->point == v)return false;}for (auto i = ver[v].group.begin(); i != ver[v].group.end(); i++){if (i->point == u)return false;}if (u == v)return false;if (have_dir){Edges++;ver[u].creat_Point(v, 1);return true;}else{Edges++;ver[u].creat_Point(v, 1);ver[v].creat_Point(u, 1);return true;}return true;}//有权图插入一条边bool Insert_Edge(int u, int v, TypeOfEdge w){if (!(0 <= u && u < Vers))return false;if (!(0 <= v && v < Vers))return false;for (auto i = ver[u].group.begin(); i != ver[u].group.end(); i++){if (i->point == v)return false;}for (auto i = ver[v].group.begin(); i != ver[v].group.end(); i++){if (i->point == u)return false;}if (u == v)return false;if (have_dir){Edges++;ver[u].creat_Point(v, w);return true;}else{Edges++;ver[u].creat_Point(v, w);ver[v].creat_Point(u, w);return true;}return true;}//删除边 (外壳:有向(删除1条边), 无向(删除2条边))bool del_Edge(int u, int v){if (!(0 <= u && u < Vers))return false;if (!(0 <= v && v < Vers))return false;if (u == v)return false;bool ok = true;if(have_dir)for (auto i = ver[u].group.begin(); i != ver[u].group.end(); i++){if (i->point == v){ver[u].group.erase(i);Edges--;return true;}}else{for (auto i = ver[u].group.begin(); i != ver[u].group.end(); i++){if (i->point == v){ver[u].group.erase(i);break;}}for (auto i = ver[v].group.begin(); i != ver[v].group.end(); i++){if (i->point == u){ver[v].group.erase(i);Edges--;return true;}}}return false;}//返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1int GetFirst_AdjVex(int u){if(ver[u].group.empty())return -1;return ver[u].group.begin()->point;}//返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回falseint GetNext_AdjVex(int u, int v){if (ver[u].group.size() == 1)return -1;for (auto i = ver[u].group.begin(); i != ver[u].group.end(); i++){if (i->point == v){if ((++i) == ver[u].group.end())return -1;return i->point;}}return -1;}/*+++++++++++====分割线====++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*///对G中指定顶点赋值 bool PutVer(int u, TypeOfVer data){return false;}//返回G中指定顶点的位置 int LocateVer(TypeOfVer data){return -1;}//存在边bool ExistEdge(int u, int v){return 0;}//DFS遍历(外壳部分)void DFS_Traverse(int u){return;}//BFS遍历void BFS_Traverse(int u){return;}};int main()
{int i;adjlist_graph<char, int> a;a.Auto_build();int u, v, w;cin >> u >> v;//cout << a.GetGraphKind() << endl;vector <char> ans;ans = a.GetVer();for (i = 0; i < ans.size() - 1; i++)cout << ans[i] << " ";cout << ans[i] << endl;//cout << a.GetVerNum() << endl;//cout << a.GetEdgeNum() << endl;a.Print_photo();cout << endl;cout << a.GetNext_AdjVex(u,v) << endl;return 0;
}

【邻接表】77 邻接表:顶点u的下一个邻接点相关推荐

  1. 邻接表:求指定顶点的(出)度

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

  2. 邻接表:构造只有顶点没有边的图

    文章目录 问题描述 : 输入说明 : 输出说明 : 输入范例 : 输出范例 : 基本知识 实现伪码 思路分析 实现伪码 析构函数 构造函数 事故现场 提交了三次 分析与总结 如有不妥或者疑问,请留言或 ...

  3. 邻接表:两个顶点是否相邻

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

  4. 用邻接表存储图c语言,邻接表、邻接多重表、十字链表及C语言实现

    上一节介绍了如何使用顺序存储结构存储邻接多重表和 邻接的意思是顶点之间有边或者弧存在,通过当前顶点,可以直接找到下一个顶点. 邻接表 使用邻接表存储图时,对于图中的每一个顶点和它相关的邻接点,都存储到 ...

  5. 【编译原理笔记15】运行存储分配概述,静态存储分配,栈式存储分配,调用序列和返回序列,非局部数据的访问,符号表,符号表建立

    本次笔记内容: 7-1 运行存储分配概述 7-2 静态存储分配 7-3 栈式存储分配 7-4 调用序列和返回序列 7-5 非局部数据的访问 7-6 符号表 7-7 符号表建立 本节课幻灯片,见于我的 ...

  6. crc16 c语言 非查表,CRC16CCITT(1021)的16字表长查表程序

    CRC位域4单表查表及建表原则: 左移位域4取列表16个,大端存储模式.右移位域4取行表16个,小端存储模式. 在CRC16CCITT中CRC的多项式为:左移CRC16=X16+X12+X5+1,即权 ...

  7. crc16 ibm c语言,CRC16IBM(A001)的16字表长查表程序

    本帖最后由 hotpower 于 2009-10-18 19:10 编辑 此文依据: http://blog.ednchina.com/hotpower/272834/message.aspx CRC ...

  8. java有向图邻接表入度_图的实现--邻接表(求出各顶点的出度和入度)

    #include using namespace std; #include #define MAX 100 struct ArcNode{//边结点 int adjvex;//有向边的另一个邻接点的 ...

  9. Mysql的多表查询(表添加,多表查询练习:笛卡尔积、内连接、外连接、子查询、UNION组合查询)

    https://blog.csdn.net/hanhanwanghaha宝藏女孩 欢迎您的关注! 欢迎关注微信公众号:宝藏女孩的成长日记 如有转载,请注明出处(如不注明,盗者必究) 目录 一.表的创建 ...

最新文章

  1. Cordova error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Deve
  2. Java类加载文章1(z)
  3. 模式识别的评价方法:ROC曲线, DET曲线, FPPW, FPPI
  4. python读取xlsx文件pandas_python-如何使用iPython中的pandas库读取.xlsx文件?
  5. Java培训教程:Java中的位移运算符!
  6. linux下安装编译网卡驱动
  7. matlab概率论实验 分别掷硬币1,基于Matlab的概率论仿真实验
  8. python怎么模拟浏览器交互_python+webdriver 模拟用户交互工具
  9. python爬取某人所有微博_Python爬取博客的所有文章并存为带目录的word文档(实例67)
  10. android 汽车 源码_汽车级Linux,无需Google即可运行Android等
  11. 留言板显示服务器错误,动易Cms:解读SiteFactory 留言板出现:服务器无响应,错误代码:500-动易Cms教程...
  12. SpringCloud分布式开发理解
  13. 深蓝学院-视觉SLAM理论与实践-第十二期-第2章作业
  14. 【知识分享】C语言的设计模式——责任链、观察者
  15. Layui官方js正则验证手机号,邮箱,网址,日期,身份证
  16. 全球经济寒冬将至?且看顶级资本大鳄的大数据分析预测
  17. 免费WebCamps-北美,亚洲和欧洲-*立即注册*
  18. 计算机基础应用寒假作业,计算机基础寒假作业.doc
  19. ❤️软件设计师之程序设计语言与语言处理程序基础“小总结”(莽起来)❤️
  20. 仿新浪微博照片选择器

热门文章

  1. 明明输给了 SpaceX,OneWeb 为什么还能拿到英国政府的钱?
  2. 便携式禁毒采样器的基础功能
  3. 吸毒后人脸变化系统在禁毒教育展厅中的应用
  4. 如何给刚刚出厂的服务器配置IP地址(华为RH2288 v3)
  5. 计算机必修课程英语单词,《计算机专业英语》课程标准(已审核).doc
  6. 虹科PCAN在工程机械中的应用
  7. 每日一题:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
  8. android wifi tethering,新增Wi-Fi/USB Tethering功能
  9. word文档表格后面的空白页怎么删除?
  10. 计算机打印机共享失败,打印机共享失败终极解决办法