问题描述 :
目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT)。
内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)
(2)设计并实现一个算法,在已存在的图中求指定顶点的(出)度(无向图/网:度; 有向图/网:出度 )。如顶点不存在,返回-1;否则返回其对应的度。图的存储结构采用邻接表。将其加入到ADT中。
注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)
参考函数原型:
//求指定顶点的(出)度(无向图/网:度; 有向图/网:出度 )
template<class TypeOfVer, class TypeOfEdge>
int adjlist_graph<TypeOfVer, TypeOfEdge>::Get_Degree(int u);

输入说明 :
建图的输入数据格式参见建图的算法说明。(以无权图为例)
第一行:图的类型
第二行:结点数
第三行:结点集
第四行:边数
第五部分:边集
最后一行:顶点u的序号

输出说明 :
第一行:顶点集
第二部分:邻接表
空行
最后一行:顶点的度(顶点不存在:-1)

输入范例 :
DG
6
A B C D E F
6
0 1
0 2
1 3
2 3
3 4
3 5
3

输出范例 :
A B C D E F
A->2->1->nullptr
B->3->nullptr
C->3->nullptr
D->5->4->nullptr
E->nullptr
F->nullptr
(空行)
2

#include<iostream>
#include<vector>
#include<string>
#include<sstream>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
string b[10001];//用来存放顶点集
//DG(有向图)  DN(有向网)  UDG(无向图) UDN(无向网)//图的邻接表模板类原型参考如下:
//边表的顶点定义
template<class TypeOfEdge>//这个就是在边上的顶点定义
struct edgeNode{int data;TypeOfEdge weight;edgeNode<TypeOfEdge> *next;//构造函数,用于构造其他顶点(无权图)//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面edgeNode(int d,edgeNode<TypeOfEdge> *ptr=NULL){ data=d;next=ptr; }//构造函数,用于构造其他顶点(带权图)//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面edgeNode(int d,TypeOfEdge w,edgeNode<TypeOfEdge> *ptr=NULL){data=d; weight=w; next=ptr;}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;//边数string GraphKind;//图的种类标志verNode<TypeOfVer,TypeOfEdge> *verList;//按顺序存储结构存储顶点集bool Delete_Edge(int u,int v);bool DFS(int u,int num,int visited[]);//DFS遍历(递归部分)public://构造函数构造一个只有顶点没有边的图//3个参数的含义:图的类型、顶点数、顶点值adjlist_graph(string kd,int vSize,TypeOfVer d[]){GraphKind=kd;Vers=vSize;verList=new verNode<TypeOfVer,TypeOfEdge> [Vers];//建立顶点值for(int i=0;i<Vers;++i){verList[i].ver=d[i];verList[i].head=NULL;//一开始构造的时候顶点还没有相邻的顶点}}//构造函数构造一个无权图//5个参数的含义:图的类型、顶点数、顶点集、  边数和边集adjlist_graph(string kd,int vSize,TypeOfVer d[],int eSize,int **e){GraphKind=kd;Vers=vSize;Edges=eSize;verList=new verNode<TypeOfVer,TypeOfEdge> [Vers];//建立顶点值for(int i=0;i<Vers;++i){verList[i].ver=d[i];verList[i].head=NULL;//一开始构造的时候顶点还没有相邻的顶点}for(int i=0;i<Edges;++i){//从边开始构造顶点for(int j=0;j<Vers;++j){if(e[i][0]==j){if(GraphKind[0]!='U'){//有向图的情况就只有1个方向Insert_Edge(e[i][0],e[i][1]);Edges-=1;break;}else{//无向图的表结点的个数是边数的2倍Insert_Edge(e[i][0],e[i][1]);Insert_Edge(e[i][1],e[i][0]);Edges-=2;break;}}}}}//构造函数构造一个有权图//6个参数的含义:图的类型、顶点数、顶点集、      边数、边集         权集adjlist_graph(string kd,int vSize,TypeOfVer d[],int eSize,int **e,TypeOfEdge w[]);bool GraphisEmpty(){ return Vers==0; }//判断图空否string GetGraphKind(){ return GraphKind; }//返回图的类型int* GetVerNum(){ return &Vers; }//取得当前顶点数int* GetEdgeNum(){ return &Edges; }  //取得当前边数bool GetVer(int u,TypeOfVer &data){//取得G中指定顶点的值return true;}//返回G中指定顶点u的第一个邻接顶点的位序(顶点集)//若顶点在G中没有邻接顶点,则返回-1int GetFirstAdjVex(int u,int &v){if(verList[u].head!=NULL){v=verList[u].head->data;return v;}v=-1;return -1;}int GetNextAdjVex(int u,int v,int w);//返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回falsebool PutVer(int u,TypeOfVer data);//对G中指定顶点赋值bool InsertVer(const TypeOfVer data);//往G中添加一个顶点int LocateVer(TypeOfVer data);//返回G中指定顶点的位置//求指定顶点的(出)度  (无向图/网:度; 有向图/网:出度 )int Get_Degree(int u){if(u<0||u>=Vers)return -1;int k=0;edgeNode<TypeOfEdge> *p=verList[u].head;while(p){++k;p=p->next;}return k;}//求有向图指定顶点的入度int Get_InDegree(int u){if(u<0||u>=Vers||GraphKind[0]=='U')//顶点不存在/非有向图返回-1return -1;bool flag=false;int k=0;for(int i=0;i<Vers;++i){if(i==u)continue;edgeNode<TypeOfEdge> *p=verList[i].head;while(p){if(p->data==u){++k;flag=true;}p=p->next;}}return flag ? k : -1;//如果入度不为0,返回k,否则返回-1}//检查指定2个顶点是否是邻接顶点bool ExistEdge(int u,int v){if(GraphKind[0]=='U'){//如果是无向图的情况edgeNode<TypeOfEdge> *p=verList[u].head;while(p){//只需要遍历一个就行if(p->data==v)return true;p=p->next;}}else{edgeNode<TypeOfEdge> *px=verList[u].head;while(px){if(px->data==v)return true;px=px->next;}edgeNode<TypeOfEdge> *py=verList[v].head;while(py){if(py->data==u)return true;py=py->next;}}return false;}//输出顶点集void PrintVer(){for(int i=0;i<Vers;++i){if(i==0)cout<<verList[i].ver;elsecout<<" "<<verList[i].ver;}cout<<endl;}//输出邻接表void PrintAdjList(){for(int i=0;i<Vers;++i){cout<<verList[i].ver;if(verList[i].head!=NULL){edgeNode<TypeOfEdge> *p=verList[i].head;//从顶点开始遍历while(p){cout<<"->"<<p->data;p=p->next;}cout<<"->nullptr"<<endl;}elsecout<<"->nullptr"<<endl;}}//无权图插入一条边bool Insert_Edge(int u,int v){//u是起点,v是终点if(u<0||u>=Vers||v<0||v>=Vers)//不在范围内时无法插入,返回falsereturn false;if(verList[u].head!=NULL){edgeNode<TypeOfEdge> *p=verList[u].head;//这个是判断如果本来就存在这条边的情况while(p){if(p->data==v)return false;p=p->next;}}edgeNode<TypeOfEdge> *x=new edgeNode<TypeOfEdge>(v);//直接使用构造函数赋值//x.data=v;不要这么写x->next=verList[u].head;//这里面都没有->next  这个指针!!!!!!!verList[u].head=x;++Edges;//边数加一return true;}//有权图插入一条边bool Insert_Edge(int u,int v,TypeOfEdge w);//往G中删除一个顶点bool DeleteVer(int data){//因为题中传入的参数就是顶点的序号,根本不是顶点本身if(data<0||data>=Vers)//如果不在范围内返回falsereturn false;edgeNode<TypeOfEdge> *pw=verList[data].head;int k=0;//用来记录被删除的顶点有多少边与之相连if(GraphKind[0]=='U'){while(pw){//如果是无向图只需要记录要被删除的边表中有多少结点就够了++k;edgeNode<TypeOfEdge> *po=pw;pw=pw->next;delete po;}}else{//如果是有向图,我们需要遍历整个链表edgeNode<TypeOfEdge> *rp=verList[data].head;while(rp){//这个循环是记录被删除顶点的边表的结点个数++k;rp=rp->next;}for(int i=0;i<Vers;++i){//这个循环就是记录其他链表中有多少是和被删除顶点有关的边edgeNode<TypeOfEdge> *r=verList[i].head;while(r){if(r->data==data)++k;r=r->next;}}}Edges-=k;//减掉边只有的边数for(int i=data;i<Vers-1;++i){//将后面的顶点往前移一位verList[i].ver=verList[i+1].ver;verList[i].head=verList[i+1].head;//指针也要往前移一位}--Vers;//PrintAdjList();//输出邻接表用来测试顶点和指针的移动是否正确for(int i=0;i<Vers;++i){edgeNode<TypeOfEdge> *px=verList[i].head;edgeNode<TypeOfEdge> *py=verList[i].head;while(px==py){//这个是判断如果与顶点结点相连的就是要删除的结点的情况if(px==py&&px==NULL&&py==NULL)break;else if(px->data==data){px=px->next;verList[i].head=px;edgeNode<TypeOfEdge> *q=py;py=py->next;delete q;}else if(px->data>data){--(px->data);px=px->next;}}while(px){//当px在前,py在后时if((px->data)>data){--(px->data);px=px->next;}else if(px->data==data){//如果相等的话就删除这个结点edgeNode<TypeOfEdge> *q=px;py->next=px->next;px=px->next;delete q;continue;}else if((px->data)<data)px=px->next;py=py->next;}}return true;}bool DeleteEdge(int u,int v);//删除边 (外壳:有向(删除1条边), 无向(删除2条边))void DFS_Traverse(int u);//DFS遍历(外壳部分)void BFS_Traverse(int u);//BFS遍历//~adjlist_graph(); //析构函数
};template<class TypeOfVer,class TypeOfEdge>
void shuchu(adjlist_graph<TypeOfVer,TypeOfEdge> &tu,int n){//cout<<tu.GetGraphKind()<<endl;int* x;//个数是int型x=tu.GetVerNum();//cout<<*x<<endl;//输出顶点个数tu.PrintVer();//输出顶点集TypeOfEdge* we;we=tu.GetEdgeNum();//cout<<*we<<endl;//输出边数tu.PrintAdjList();//输出邻接表
}int main(){string str;//图的类型int n,m;//顶点数和边数getline(cin,str);cin>>n;//输入顶点个数for(int i=0;i<n;++i)cin>>b[i];//输入顶点集合cin>>m;//输入边数int **e;e=new int* [m];for(int i=0;i<m;++i)e[i]=new int [2];for(int i=0;i<m;++i)cin>>e[i][0]>>e[i][1];//输入边集adjlist_graph<string,int> tu(str,n,b,m,e);//使用构造函数构造图的类int no,to;//指定的要删除的顶点cin>>no;shuchu(tu,n);cout<<endl;cout<<tu.Get_Degree(no)<<endl;//shuchu(tu,n);return 0;
}
在邻接表的情况下:

1.如果是有向图求顶点的出度,那就是顶点后买连接的边表的结点的个数。
2.如果是无向图求顶点的出度,也是该顶点后面连接的边表的结点的个数,因为无向图只要有2个顶点相连,那么这2个顶点的边表都会有对方的顶点序号的。

所以求某个顶点的(出)度时,就是当前顶点的边表的结点的个数。

邻接表:求指定顶点的(出)度相关推荐

  1. 根据邻接表求深度优先搜索和广度优先搜索_深度优先搜索/广度优先搜索与java的实现...

    度:某个顶点的度就是依附于该顶点的边的个数 子图:一幅图中所有边(包含依附边的顶点)的子集 路径:是由边顺序连接的一系列定点组成 环:至少含有一条边且终点和起点相同的路径 连通图:如果图中任一个到另一 ...

  2. 4003基于邻接表的新顶点的增加(C++,附详细解析)

    描述 给定一个无向图,在此无向图中增加一个新顶点. 输入 多组数据,每组m+2行.第一行有两个数字n和m,代表有n个顶点和m条边.顶点编号为1到n.第二行到第m+1行每行有两个数字h和k,代表边依附的 ...

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

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

  4. mysql 邻接表_图的邻接表存储结构详解

    通常,图更多的是采用链表存储,具体的存储方法有 3 种,分别是邻接表.邻接多重表和十字链表. 本节先讲解图的邻接表存储法.邻接表既适用于存储无向图,也适用于存储有向图. 在具体讲解邻接表存储图的实现方 ...

  5. 采用邻接表存储结构,编写一个判别无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的算法。

    以邻接表存储的有向图中是否存在有顶点Vi到Vj顶点的路径(i!=j). 问题描述:试基于图的深度优先搜索策略编写一程序,判别以邻接表存储的有向图中是否存在有顶点Vi到Vj顶点的路径(i!=j). 输入 ...

  6. 4005基于邻接表的顶点的删除(C++,附思路)

    描述 给定一个无向图,在此无向图中删除一个顶点. 输入 多组数据,每组m+2行.第一行有两个数字n和m,代表有n个顶点和m条边.顶点编号为1到n.第二行到第m+1行每行有两个数字h和k,代表边依附的两 ...

  7. 邻接表:有权图获取边的权值

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

  8. 数据结构之图(三)——邻接表

    邻接表表示法(链式) 顶点: 按编号顺序将顶点数据存储在一维数组中. 关联同一顶点的边: 用线性链表存储. 如果有边\弧的信息,还可以在表结点中增加一项, 无向图的邻接表 例子: 特点: 邻接表不唯一 ...

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

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

最新文章

  1. 常用的python数值处理函数,python常用数值函数总结
  2. 解决pip安装时出现报错TypeError: unsupported operand type(s) for -=: ‘Retry‘ and ‘int‘
  3. 9、计算机图形学——纹理的应用(环境贴图、凸凹贴图、法线贴图以及位移贴图)
  4. 《大型网站技术架构:核心原理及案例分析》阅读笔记01
  5. ddr2是几代内存_内存系列一:快速读懂内存条标签
  6. pat根据中序遍历和先序遍历_算法题399:从前序与中序遍历序列构造二叉树
  7. 如何找到SAP ECC事务码升级到S4HANA后对应的新事务码
  8. c语言中条件编译相关的预编译指令
  9. SQL Server 数据库的维护(四)__游标(cursor)
  10. 从代码内部:骆驼路由引擎第一部分
  11. 类重复引用_JVM类加载从JDK来看
  12. 你见过股市亏最惨的有多惨?
  13. SQL Server 查询性能优化——覆盖索引(一)
  14. canvas实现web excel高性能表格(发布开源)
  15. 基于 FFMPEG 的视频解码(libavcodec ,致敬雷霄骅)
  16. 央行数字货币:第三方支付产业新变量
  17. 中继器,集线器,网桥的区别
  18. flash debug版本
  19. 如果这篇文章说不清epoll的本质,那就过来掐死我吧! (2)
  20. mysql 1032错误_3分钟解决MySQL 1032 主从错误

热门文章

  1. idea插件开发(5)-Swing图形化设计
  2. 【论文分享】用于中文零代词解析的带有配对损失的分层注意力网络
  3. 多媒体网络的分布式知识要点
  4. python3基础教程雪峰_[雪峰磁针石博客]python3快速入门教程9重要的标准库
  5. Python描述 LeetCode 334. 递增的三元子序列
  6. Mysql中数据类型括号中的数字代表的含义
  7. 国内外云主机服务对比
  8. 什么是DTO 什么是KYC
  9. 用easyPoi导出excel,带多sheet,合并单元格,合计,单元格金额类型
  10. 拜托,面试请不要再问我 Spring Cloud Alibaba 底层原理