图的邻接多重表和搜索(C++版本)
最近在学数据结构,学到图这一章,网上的C++版本的代码乱得不行,所以自己写了一个完整C++版本的放这里。
用邻接多重表表示一个无向图,并给出DFS和BFS搜索代码。邻接多重表好处就是贼直观,几条边就几个边表的元素。
代码如下:
边表节点定义(其实就是边的定义)
typedef struct EdgeNode //邻接多重表
{
int iVertex;
EdgeNode* iLink;
int jVertex;
EdgeNode* jLink; };
顶点表节点的定义
template <typename Type>
struct VextexNode //邻接多重表的顶点表
{
Type Data;
EdgeNode* TailLink;
Mark Flag;
};
最后是图的模板类
#ifndef MULADJACENCYLIST_H
#define MULADJACENCYLIST_H
#include "SideNode.h"
#include "VexNode.h"
#include <iostream>
#include <vector>
#include <list>
#include <set>
using namespace std; template <typename Type, int N>
class MulAdjacencyList
{
public:
MulAdjacencyList();
~MulAdjacencyList();
void AddEdge();
int DeleteEdge(int x, int y);
void DFS(int x, const Type& Value);
void BFS(int x, const Type& Value);
private:
int InitEdgeNum(); //构造函数中先输入图的边数
int NextIndex(int CurIndex); //查找最近的一个邻接点,CurIndex为点的下标而不是值
void BFSHelper(set <int> SourceList, const Type& Value); //BFS真正的递归函数
void AllNextIndex(int i); //和i相连的所有邻接点,i为点的下标而不是值
VextexNode <Type> VertexArray[N]; //顶点表
EdgeNode* LastPtr(int x);
int EdgeNums; //当前的边数
vector <int> Temp; //用来存放搜索结果的容器
set <int> TempList; //用来存放AllNextIndex结果的容器
}; template <typename Type, int N>
void MulAdjacencyList<Type, N>::AddEdge() //添加一条x到y的无向边
{
cout << "Enter the edge wanna insert!" << endl;
int i, j;
if (cin >> i >> j)
{
EdgeNode* TarPtr = new EdgeNode;
TarPtr->iVertex = i;
TarPtr->jVertex = j;
TarPtr->iLink = VertexArray[i].TailLink;
TarPtr->jLink = VertexArray[j].TailLink;
VertexArray[i].TailLink = TarPtr;
VertexArray[j].TailLink = TarPtr;
EdgeNums++;
}
else
cin.clear();
} template <typename Type, int N>
int MulAdjacencyList<Type, N>::InitEdgeNum()
{
cout << "Enter the quantity of edges!"<< endl;
cin >> EdgeNums;
return EdgeNums;
} template <typename Type, int N>
EdgeNode* MulAdjacencyList<Type, N>::LastPtr(int x) //找到和x相关的最后一条边
{
EdgeNode* Temp = VertexArray[x].TailLink;
EdgeNode* LastTemp = Temp;
while (Temp != NULL)
{
if (Temp->iVertex == x)
{
LastTemp = Temp;
Temp = Temp->iLink;
}
else if (Temp->jVertex == x)
{
LastTemp = Temp;
Temp = Temp->jLink;
}
}
return LastTemp;
} template <typename Type, int N>
MulAdjacencyList <Type, N>::MulAdjacencyList()
{
cout << "enter the vertex for the graph!" << endl;
for (int i = ; i != N; ++i)
{
cin >> VertexArray[i].Data;
VertexArray[i].TailLink = NULL;
VertexArray[i].Flag = No;
}
int Temp = InitEdgeNum();
for (int i = ; i != Temp; ++ i)
AddEdge();
} template <typename Type, int N>
int MulAdjacencyList<Type, N>::DeleteEdge(int x, int y) //删除x到y的一条无向边
{
if (x == y)return ;
EdgeNode* Q = VertexArray[x].TailLink; //Q的下一条边就是要删除的边
EdgeNode* P = VertexArray[x].TailLink; //先从x出发找到要删除的边,调整完x的边的次序,得到指针,最后再删除
if (P && P->jVertex == y) //假如第一条边就是待删除的边, P是前向判断,避免P为NULL的情况下还执行P->jVertex
VertexArray[x].TailLink = P->iLink;
else if (P && P->iVertex == y)
VertexArray[x].TailLink = P->jLink;
else //假如第一条边不是要删除的边,则向下查找
{
while (P)
{
if (P->iVertex == x && P->jVertex != y)//不是要删除的边
{
Q = P;
P = P->iLink;
}
else if (P->jVertex == x && P->iVertex != y)
{
Q = P;
P = P->jLink;
}
else //找到了邻接点y
break;
}
if (P == NULL)
{
return ; //这里可以加入一句警告“Not Found”
}
else if (P->iVertex == x && P->jVertex == y) //找到了边(x,y),调整x的边的次序
{
if (Q->iVertex == x)
Q->iLink = P->iLink;
else
Q->jLink = P->iLink;
}
else if (P->iVertex == y && P->jVertex == x)
{
if (Q->iVertex == x)
Q->iLink = P->jLink;
else
Q->jLink = P->jLink;
}
} P = VertexArray[y].TailLink; //从y出发开始查找,调整y的边的次序
if (P && P->iVertex == x)
VertexArray[y].TailLink = P->jLink;
else if (P && P->jVertex == x)
VertexArray[y].TailLink = P->iLink;
else
{
while (P != NULL)
{
if (P->iVertex == y && P->jVertex != x)
{
Q = P;
P = P->iLink;
}
else if (P->jVertex == y && P->iVertex != x)
{
Q = P;
P = P->jLink;
}
else
break;
}
if (P == NULL) //由于上面打了一次警告,这里就不打警告了
return ;
else if (P->iVertex == y && P->jVertex == x)
{
if (Q->iVertex == y)
Q->iLink = P->iLink;
else
Q->jLink = P->iLink;
}
else if ((P->jVertex == y && P->iVertex == x))
{
if (Q->iVertex == y)
Q->iLink = P->jLink;
else
Q->jLink = P->jLink;
}
}
cout << x << endl << y << endl<<"yici"<<endl;
if (P != NULL) delete P; //调整完线序了,删掉边
--EdgeNums;
return ;
} template <typename Type, int N>
MulAdjacencyList <Type, N>::~MulAdjacencyList()
{
for (int i = ; i != N; ++i)
{
for (int j = ; j != N; ++j)
DeleteEdge(i,j);
}
} template <typename Type, int N>
void MulAdjacencyList <Type, N>::AllNextIndex(int i) //找到和i相关联的所有的点
{
EdgeNode* Ptr = VertexArray[i].TailLink;
while (Ptr != NULL)
{
if (Ptr->iVertex == i)
{
if (VertexArray[Ptr->jVertex].Flag != Yes)TempList.insert(Ptr->jVertex);
Ptr = Ptr->iLink;
}
else
{
if (VertexArray[Ptr->iVertex].Flag != Yes)TempList.insert(Ptr->iVertex);
Ptr = Ptr->jLink;
}
}
} template <typename Type, int N>
int MulAdjacencyList <Type, N>::NextIndex(int CurIndex)
{
EdgeNode* Ptr = VertexArray[CurIndex].TailLink;
while (Ptr != NULL)
{
if (Ptr->iVertex == CurIndex)
{
if (VertexArray[Ptr->jVertex].Flag == No){
return Ptr->jVertex;
}
else
Ptr = Ptr->iLink;
}
else if (Ptr ->jVertex == CurIndex)
{
if (VertexArray[Ptr->iVertex].Flag == No){
return Ptr->iVertex;
}
else
Ptr = Ptr->jLink;
}
}
if (Ptr == NULL) { return N; }
} template <typename Type, int N>
void MulAdjacencyList <Type, N>::DFS(int x, const Type& Value) //x为起始的下标,Value为查找的值
{
if (VertexArray[x].Data == Value)
{
Temp.push_back(x);
}
VertexArray[x].Flag = Yes;
int TempIndex = NextIndex(x);
while (TempIndex != N)
{
DFS(TempIndex, Value);
TempIndex = NextIndex(x);
}
for (vector <int>::const_iterator i = A.Temp.begin(); i != A.Temp.end(); ++i) //打印找到的元素
cout << *i << endl;
} template <typename Type, int N>
void MulAdjacencyList <Type, N>::BFSHelper(set <int> SourceList,const Type& Value)
{
if (!SourceList.empty())
{
for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i)
{
VertexArray[*i].Flag = Yes;
if (VertexArray[*i].Data == Value)
Temp.push_back(*i);
}
for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i)
{
AllNextIndex(*i);
}
SourceList = TempList;
TempList.clear();
BFSHelper(SourceList, Value);
}
} template <typename Type, int N>
void MulAdjacencyList <Type, N>::BFS(int x, const Type& Value)
{
set <int> Set;
Set.insert(x);
BFSHelper(Set, Value);
}
#endif
大类的代码有点乱,先挖个坑以后有空再来填上,希望对各位和自己有帮助。
图的邻接多重表和搜索(C++版本)的更多相关文章
- 图->存储结构->邻接多重表
文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...
- 数据结构学习笔记05图 (邻接矩阵 邻接表-->BFS DFS、最短路径)
数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边& ...
- 数据结构之---C语言实现图的邻接表存储表示
// 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #defi ...
- 图的邻接表存储表示(C)
//---------图的邻接表存储表示------- #include<stdio.h> #include<stdlib.h> #define MAX_VERTEXT_NUM ...
- 图的邻接表存储 c实现
图的邻接表存储 c实现 (转载) 用到的数据结构是 一个是顶点表,包括顶点和指向下一个邻接点的指针 一个是边表, 数据结构跟顶点不同,存储的是顶点的序号,和指向下一个的指针 刚开始的时候把顶点表初始化 ...
- 基于visual Studio2013解决算法导论之053图的邻接表表示
题目 图的邻接表表示 解决代码及点评 // 图的邻接表表示.cpp : 定义控制台应用程序的入口点. // #include <iostream> #include <sta ...
- c_数据结构_图_邻接表
课程设计------邻接表 图的遍历实现课程设计:https://files.cnblogs.com/files/Vera-y/图的遍历_课程设计.zip #include<stdio.h> ...
- 图论——图的邻接表实现——Java语言(完整demo)
1.图的简单实现方法——邻接矩阵 表示图的一种简单的方法是使用一个一维数组和一个二维数组,称为领接矩阵(adjacent matrix)表示法. 对于每条边(u,v),置A[u,v]等于true:否则 ...
- 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...
随机推荐
- iOS Core Animation之CALayer心得
使用CALayer的mask实现注水动画效果 Core Animation一直是iOS比较有意思的一个主题,使用Core Animation可以实现非常平滑的炫酷动画.Core animtion的AP ...
- [题解]洛谷月赛 Hello World(升级版)
题目背景 T1答案要mod1000000007(10^9+7),请重新提交,非常抱歉! 一天,智障的pipapi正在看某辣鸡讲义学程序设计. 题目描述 在讲义的某一面,他看见了一篇文章.这篇文章由英文 ...
- CentOS下的Memcache安装步骤(Linux+Nginx+PHP+Memcached)
一.源码包准备 服务器端主要是安装memcache服务器端下载:http://memcached.googlecode.com/files/memcached-1.4.4.tar.gz另外,Memca ...
- 第十一周PSP
第十一周PSP 工作周期:11.24-12.1 本周PSP: C类型 C内容 S开始时间 ST结束时间 I中断时间 T净时间(分) 11月29 文档 写随笔 19:00min 19:30min ...
- I/O复用
1.I/O模型 一个输入操作通常包括两个不同阶段:等待数据准备好:从内核到进程拷贝数据. 阻塞I/O模型 非阻塞I/O模型 I/O复用模型:内核发现进程指定的一个或多个I/O条件就绪,它就通知进程,由 ...
- Linq group
using System;using System.Collections.Generic;using System.Linq; public class MyClass{ public static ...
- a 标签提交前验证
最近在做验证的时候遇到了submit()与onsubmit()事件冲突的问题,本来想在a标签中添加submit()进行表单的提交,然后在 form中添加onsubmit事件触发验证方法.结果行不通,最 ...
- Git之VS2010实践
对于我们经常在VS2010下编程的开发人员来说,强大的SCM工具Git貌似对我们很陌生.对于Git,我在我的另一篇博客<Git学习笔记>中已做过介绍,下面我再简单介绍一下Git在VS201 ...
- Flask备注4(Structure)
Flask备注4(Structure) package 通过Flask可以非常简单的通过一个module(一个py文件)创建一个简单的application.这种简单程序的文件结构如下: /youra ...
- MySQL——保证数据的完整性
为了防止垃圾的产生,从而影响数据库的执行效率. 1实体完整性——行数据的有效性 唯一约束(unique).主键约束(primary key) 2域完整性——列数据的有效性 非空约束(not nul ...