定义邻接表存储的图类。
[实验要求]

(1)创建一个邻接表存储的图;
(2)返回图中指定边的权值;
(3)插入操作:向图中插入一个顶点,插入一条边;
(4)删除操作:从图中删除一个顶点,删除一条边;
(5)图的广度优先遍历;
(6)基于迪杰斯特拉算法求最短路径。【选作】

[截图]

- 实验例图

- 邻接表

- 操作截图

[实现代码]
一共四个文件 :AQueue.h、Graph_List.h、Graph_List.cpp和main.cpp

- AQueue.h(自己实现的队列,也可以用C++库中的标准队列需要将代码中的相关代码替换下)

#include<iostream>
using namespace std;
template<class T>
class AQueue {
private: int front; /*队首所在数组元素下标*/
int rear; /*新元素要插入的位置(下标)*/
int count; /*队列中元素个数*/
T* QArray; /*存放队列元素的数组*/
int size; /*存放队列的数组规模*/
public: AQueue(int MaxQueueSize = ); /*构造函数*/
~AQueue(void) { delete[] QArray; } /*析构函数*/
bool QInsert(const T& item); /*向队尾插入元素item*/
bool QDelete(T& item); /*删除队首元素并将该元素值保存至item*/
void QClear(void) { front = rear = count = ; } /*清空队列*/
bool QFront(T& item); /*存取队首元素值*/
bool isEmpty(void)const { return count == ; } /*检测队列是否为空*/
bool isFull(void)const { return count == size; } /*检测队列是否为满*/
}; //构造函数
template<class T>
AQueue<T>::AQueue(int MaxQueueSize)
{
size = MaxQueueSize;
QArray = new T[MaxQueueSize];
front = ; rear = ; count = ;
} //将元素item插入队尾
template<class T>
bool AQueue<T>::QInsert(const T& item)
{
if (isFull())
{
cout << "Inserting into a full Queue!" << endl;
return false;
} //若队列已满
QArray[rear] = item; //添加队尾元素
rear = (rear + ) % size; //修改对位指针
count++; //队列长度+1
return true;
} //删除队首元素,并将其元素值赋给变量item
template<class T>
bool AQueue<T>::QDelete(T& item)
{
if (isEmpty())
{
cout << "Deleting from an empty queue!" << endl;
return false;
}
item = QArray[front];
front = (front + ) % size; //front顺时针移动一格
count--; //队列长度-1
return true;
} //将队首元素值赋给变量item
template<class T>
bool AQueue<T>::QFront(T& item)
{
if (isEmpty())
{
cout << "Reading from an empty queue!" << endl;
return false;
}
item = QArray[front];
return true;
}

- Graph_List.h

#ifndef _GRAPH_LIST_H
#define _GRAPH_LIST_H
#include<iostream>
using namespace std;
const int maxsize=;
const int maxweight=;
struct Edge{
friend class Graph_List;
int VerAdj;
int cost;
Edge *link;
};
struct Vertex{
friend class Graph_List;
int VerName;
Edge *adjacent;
};
class Graph_List{
private:
Vertex *Head;
int size;
public:
Graph_List();
virtual ~Graph_List();
int getweight(const int&v1,const int&v2);
int getfirstneighbor(const int v);
int getnextneighbor(const int v1,const int v2);
void insterVertex(const int&v);
void insterEdge(const int v1,const int v2,int weight);
void deleteVertex(const int&v);
void deleteEdge(const int v1,const int v2);
void deleteEdge1(const int v1,const int v2);
void BFS(const int s);
void DShortestPath(const int v);
void print();
};
#endif

- Graph_List.cpp

#include<iostream>
#include"Graph_List.h"
#include"AQueue.h"
using namespace std;
Graph_List::Graph_List(){
int e,from,to,weight;
Head=new Vertex[maxsize];
cout<<"输入结点个数:"<<endl;
cin>>size;
for(int i=;i<size;i++){
Head[i].VerName=i;
Head[i].adjacent=NULL;
}
cout<<"输入边个数:"<<endl;
cin>>e;
for(int i=;i<e;i++){
cout<<"始结点、终止结点、权重:"<<endl;
cin>>from>>to>>weight;
Edge*p=new Edge;
p->VerAdj=to;
p->cost=weight;
p->link=NULL;
Edge*q=Head[from].adjacent;
if(q==NULL)
Head[from].adjacent=p;
else{
while(q->link!=NULL)
q=q->link;
q->link=p;
}
}
}
Graph_List::~Graph_List(){
for(int i=;i<size;i++){
Edge *p=Head[i].adjacent;
while(p!=NULL){
Head[i].adjacent=p->link;
delete p;
p=Head[i].adjacent;
}
}
delete[]Head;
}
int Graph_List::getweight(const int&v1,const int&v2){
if(v1==v2) return ;
if(v1==-||v2==-)return ;
if(v1>=size||v2>=size)return ;
Edge *p=Head[v1].adjacent;
while(p!=NULL){
if(p->VerAdj==v2)
return p->cost;
p=p->link;
}
return ;
}
int Graph_List::getfirstneighbor(const int v){
if(v==-)return -;
Edge*p=Head[v].adjacent;
if(p!=NULL)
return p->VerAdj;
else
return -;
}
int Graph_List::getnextneighbor(const int v1,const int v2){
if(v1!=-&&v2!=-){
Edge*p=Head[v1].adjacent;
while(p->VerAdj!=v2&&p!=NULL)
p=p->link;
if(p==NULL) return -;
p=p->link;
if(p==NULL) return -;
return p->VerAdj;
}
}
void Graph_List::insterVertex(const int&v){
if(v<size&&Head[v].VerName!=-){
cout<<"此结点已存在"<<endl;
return;
}
size++;
Head[size-].VerName=v;
Head[size-].adjacent=NULL;
}
void Graph_List::insterEdge(const int v1,const int v2,int weight){
Edge*p=Head[v1].adjacent;
Edge*q=new Edge;
if(v1==-||v2==-){
cout<<"结点不存在!"<<endl;
return;
}
if(v1>size){
cout<<"输入错误!"<<endl;
return;
}
if(v2>size){
cout<<"输入错误!"<<endl;
return;
}
if(v1==v2){
cout<<"输入错误!"<<endl;
return;
}
q->VerAdj=v2;
q->cost=weight;
if(p==NULL)
Head[v1].adjacent=q;
else{
while(p->link!=NULL)
p=p->link;
p->link=q;
}
q->link=NULL;
}
void Graph_List::deleteVertex(const int&v){
if(v>=size){
cout<<"输入错误!"<<endl;
return;
}
if(Head[v].VerName!=-){
Edge *p=Head[v].adjacent;
int i;
while(p!=NULL){
Head[v].adjacent=p->link;
delete p;
p=Head[v].adjacent;
}
Head[v].VerName=-;
for(i=;i<size;i++){
if(Head[i].VerName!=-){
deleteEdge1(i,v);
}
}
size--;
}
else
cout<<"结点不存在!"<<endl;
}
void Graph_List::deleteEdge1(const int v1,const int v2){
if(v1==v2){
return;
}
Edge *p=Head[v1].adjacent,*q;
while(p!=NULL){
if((Head[v1].adjacent)->VerAdj==v2){
Head[v1].adjacent=p->link;
delete p;
return;
}
else{
if(p->VerAdj==v2){
q->link=p->link;
delete p;
return;
}
}
q=p;
p=p->link;
}
if(p==NULL){
return;
}
}
void Graph_List::deleteEdge(const int v1,const int v2){
if(v1==v2){
cout<<"输入错误!"<<endl;
return;
}
if(v1>=size){
cout<<"输入错误!"<<endl;
return;
}
if(v2>=size){
cout<<"输入错误!"<<endl;
return;
}
Edge *p=Head[v1].adjacent,*q;
while(p!=NULL){
if((Head[v1].adjacent)->VerAdj==v2){
Head[v1].adjacent=p->link;
delete p;
return;
}
else{
if(p->VerAdj==v2){
q->link=p->link;
delete p;
return;
}
}
q=p;
p=p->link;
}
if(p==NULL){
cout<<"无此边!"<<endl;
}
}
void Graph_List::BFS(const int s){
if(s>=size){
cout<<"输入错误!"<<endl;
return;
}
int *visited=new int[size];
for(int k=;k<size;k++)
visited[k]=;
cout<<s<<" ";
visited[s]=;
AQueue<int>q;
q.QInsert(s);
while(!q.isEmpty()){
int v;
q.QDelete(v);
int w=getfirstneighbor(v);
while(w!=-){
if(!visited[w]){
cout<<w<<" ";
visited[w]=;
q.QInsert(w);
}
w=getnextneighbor(v,w);
}
}
delete []visited;
}
void Graph_List::DShortestPath(const int v){
int u,k;
int max=;
Edge *p;
int n=size;
int *path= new int[size];
int *dist= new int[size];
int *s=new int[n];//数组是s[i]记录i是否被访问过
for(int i=;i<n;i++) {path[i]=-;dist[i]=max;s[i]=; };//数组初始化
dist[v]=;s[v]=; //初始顶点v的数组值
p=Head[v].adjacent;
u=v;
for(int j=;j<n;j++)
{ //循环(2):修改u邻接顶点的s【】值path【】值和dist【】值
while(p!=NULL){
k=p->VerAdj;
if(s[k]!=&&dist[u]+p->cost<dist[k])
{
dist[k]=dist[u]+p->cost;
path[k]=u; }
p=p->link;
} ;
//循环(3):修改u邻接顶点的s【】值path【】值和dist【】值
int ldist=max;
for(int i=;i<n;i++)
if(dist[i]>&&dist[i]<ldist&&s[i]==){ldist=dist[i];u=i; }
s[u]=;//访问u
p=Head[u].adjacent;//p为u的边链的头指针
}
//for(int i=0;i<n;i++)cout<<path[i]<<" ";
//cout<<endl;
for(int i=;i<n;i++)cout<<dist[i]<<" ";
delete []path;
delete[] dist;
}
void Graph_List::print(){
Edge*p;
int i;
for(i=;i<size;i++){
if(Head[i].VerName!=-){
cout<<Head[i].VerName;
p=Head[i].adjacent;
while(p!=NULL){
cout<<"→"<<p->VerAdj<<" "<<p->cost<<" ";
p=p->link;
}
cout<<endl;
}
}
}

- main.cpp

#include<iostream>
#include"Graph_List.h"
#include"Graph_List.cpp"
using namespace std;
int main(){
Graph_List a;
a.print();
int x,y,z,k;
cout<<"请选择功能:"<<endl;
cout<<"1.查询权重"<<endl;
cout<<"2.插入结点"<<endl;
cout<<"3.插入边"<<endl;
cout<<"4.删除结点"<<endl;
cout<<"5.删除边"<<endl;
cout<<"6.广度优先遍历"<<endl;
cout<<"7.求最短路径"<<endl;
while(){
cout<<"请选择功能:"<<endl;
cin>>k;
switch(k){
case :
cout<<"输入想要查询边的起始、终止结点:"<<endl;
cin>>x>>y;
z=a.getweight(x,y);
cout<<"权重为:"<<z<<endl;
break;
case :
cout<<"输入想要插入的结点:"<<endl;
cin>>x;
a.insterVertex(x);
a.print();
break;
case :
cout<<"输入想要插入的边信息:"<<endl;
cin>>x>>y>>z;
a.insterEdge(x,y,z);
a.print();
break;
case :
cout<<"输入想要删除的结点:"<<endl;
cin>>x;
a.deleteVertex(x);
a.print();
break;
case :
cout<<"输入想要删除的边信息:"<<endl;
cin>>x>>y;
a.deleteEdge(x,y);
a.print();
break;
case :
cout<<"输入遍历顶点:"<<endl;
cin>>x;
a.BFS(x);
cout<<endl;
break;
case :
cout<<"输入求最短路顶点:"<<endl;
cin>>x;
a.DShortestPath(x);
cout<<endl;
break;
}
}
return ;
}

数据结构C++使用邻接表实现图的更多相关文章

  1. PTA 邻接表存储图的广度优先遍历(20 分)

    6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...

  2. hdu 2647 (拓扑排序 邻接表建图的模板) Reward

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647 老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员 ...

  3. QDUOJ 生化危机 邻接表存图+BFS

    生化危机 发布时间: 2015年10月10日 18:05   时间限制: 1000ms   内存限制: 256M 描述 X博士想造福人类, 研发一种可以再生肢体的药物, 可是很不幸......研究失败 ...

  4. PTA 邻接表存储图的广度优先遍历

    试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ) 其中LGraph是邻接表存储的 ...

  5. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  6. c++邻接表存储图(无向),并用广度优先和深度优先遍历(实验)

    一开始我是用c写的,后面才发现广搜要用到队列,所以我就直接使用c++的STL队列来写, 因为不想再写多一个队列了.这次实验写了两个多钟,因为要边写边思考,太菜了哈哈. 主要参考<大话数据结构&g ...

  7. 邻接表存储图,DFS遍历图的java代码实现

    import java.util.*; public class Main{ static int MAX_VERTEXNUM = 100; static int [] visited = new i ...

  8. 三种邻接表存图模板:vector邻接表、数组邻接表、链式前向星

    vector邻接表: ; struct Edge{ int u,v,w; Edge(int _u=0,int _v=0,int _w=0){u=_u,v=_v,w=_w;} }; vector< ...

  9. SDOI2010_大陆争霸(邻接表存图)

    题目描述 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯 ...

随机推荐

  1. 集训 T1-找试场

    大致题意: 按照给定的指令移动,输出最后到达的点. 若没有走动过则输出(0,0). 基本思路 这题就是模拟,主要是判断指令的时候不太好判断, 先用字符串把指令读取进来,看看第一位是否是数字(如果是数字 ...

  2. msf stagers开发不完全指北(四): msf 中使用域前置技术隐藏流量

    msf 中使用域前置技术隐藏流量 前几篇都是说了下如何采用不同的语言开发 reverse_tcp 第二阶段,接下来将慢慢分析 reverse_http,这篇文章并不会围绕 stagers 进行讲解,这 ...

  3. Keras之对鸢尾花识别

    Keras之队鸢尾花识别 任务目标 对鸢尾花数据集分析 建立鸢尾花的模型 利用模型预测鸢尾花的类别 环境搭建 pycharm编辑器搭建python3.* 第三方库 numpy pandas sklea ...

  4. Go的100天之旅-08字符串

    目录 简介 UTF-8字符 字符串的常用操作 简介 字符串在各种编程语言中都是很基础的一种类型,在Go中字符串简单理解就是一个数组,数组里面的元素是byte类型.因此基本上拥有类似数组的全部特性.例如 ...

  5. 设计模式:singleton模式

    目的:限制类的实例个数只能是一个 例子: #define AGT_DECLARE_SINGLETON(ClassName) \ public: \ static ClassName *Instance ...

  6. 微信扫码登陆js

    先贴一个微信开发文档教程 https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.ht ...

  7. 程序员每日一乐:html动态烟花设计 3D

    3D版烟花 效果图:file:///C:/Users/QianXin/Desktop/3D%E7%83%9F%E8%8A%B1.html 经过一天的的工作或者学习是否感到枯燥乏味?现在的你是否想找些乐 ...

  8. xss原理绕过防御个人总结

    xss原理 xss产生的原因是将恶意的html脚本代码插入web页面,底层原理和sql注入一样,都是因为js和php等都是解释性语言,会将输入的当做命令执行,所以可以注入恶意代码执行我们想要的内容 x ...

  9. GhostNet: More Features from Cheap Operations

    论文:GhostNet: More Features from Cheap Operations,CVPR 2020 代码:https://github.com/iamhankai/ghostnet. ...

  10. Linux版 乐影音下载器(视频下载器) 使用方法

    如果你不知道Linux为何物,那么请回去选择前两种下载方式之一. 只提供Linux 64位的乐影音下载器(点击下载),在Linux Mint 19.1  64位.Python 3.6环境下测试能正常运 ...