数据结构C++使用邻接表实现图
定义邻接表存储的图类。
[实验要求]
(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++使用邻接表实现图的更多相关文章
- PTA 邻接表存储图的广度优先遍历(20 分)
6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...
- hdu 2647 (拓扑排序 邻接表建图的模板) Reward
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647 老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员 ...
- QDUOJ 生化危机 邻接表存图+BFS
生化危机 发布时间: 2015年10月10日 18:05 时间限制: 1000ms 内存限制: 256M 描述 X博士想造福人类, 研发一种可以再生肢体的药物, 可是很不幸......研究失败 ...
- PTA 邻接表存储图的广度优先遍历
试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ) 其中LGraph是邻接表存储的 ...
- 数据结构(11) -- 邻接表存储图的DFS和BFS
/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...
- c++邻接表存储图(无向),并用广度优先和深度优先遍历(实验)
一开始我是用c写的,后面才发现广搜要用到队列,所以我就直接使用c++的STL队列来写, 因为不想再写多一个队列了.这次实验写了两个多钟,因为要边写边思考,太菜了哈哈. 主要参考<大话数据结构&g ...
- 邻接表存储图,DFS遍历图的java代码实现
import java.util.*; public class Main{ static int MAX_VERTEXNUM = 100; static int [] visited = new i ...
- 三种邻接表存图模板: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< ...
- SDOI2010_大陆争霸(邻接表存图)
题目描述 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯 ...
随机推荐
- 我为什么不再推荐 RxJava
本文转自作者: W_BinaryTree 链接:juejin.im/post/5cd04b6e51882540e53fdfa2,如有侵权,可删除 距离上一次更新也有一段时间了,其实这篇文章我早就想写, ...
- OSCP Learning Notes - Exploit(5)
Java Applet Attacks Download virtual machines from the following website: https://developer.microsof ...
- Angular 的前世今生
目录 序言 AngularJS 简介 Angular 2.0 的动机 现如今的 Angular Angular 的核心概念 参考 序言 Angular 一般意义上是指 Angular v2 及以上版本 ...
- java opencsv解析csv文件
记一次使用opencsv解析csv文件时碰到的坑 最近在开发过程中需要解析csv文件,公司用的解析工具是opencsv,在根据opencsv的官方文档去解析时发现csv文件中含有繁体字,使用其自带的C ...
- springboot 跨域设置
/** * Configuration cors */ @Configuration public class MyConfiguration { @Bean public FilterRegistr ...
- python爬虫入门(3)----- scrapy
scrapy 简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网络 ...
- 为什么不应该使用goroutine id?
Goroutine id 的获取方式 之前做的项目中,会使用 goroutine-id(以下简称 goid) 作为日志中的一个标识参数.而 goroutine 的相关信息是不对外暴露的.想要获取 go ...
- 如何导入spring 的jar包到eclips
https://www.cnblogs.com/xxuan/p/6949640.html
- Python List sort()方法
描述 sort() 函数用于对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数.高佣联盟 www.cgewang.com 语法 sort()方法语法: list.sort(cmp=None, ...
- qemu 如何退出qemu
如何退出qemu ctrl + a 放开后,再按下x 这里字母是小写!(不要按着大写键)