图的邻接表实现_LGraph

邻接表是图的另一种有效的存储表示方法. 每个顶点u建立一个单链表, 链表中每个结点代表一条边<u, v>, 为边结点. 每个单链表相当于

邻接矩阵的一行.

adjVex域指示u的一个邻接点v, nxtArc指向u的下一个边结点. 如果是网, 增加一个w域存储边上的权值.

构造函数完成对一维指针数组a的动态空间存储分配, 并对其每个元素赋初值NULL. 析构函数首先释放邻接表中所有结点, 最后释放一维

指针数组a所占的空间.

包含的函数Exist(): 若输入的u, v无效, 则函数返回false. 否则从a[u]指示的边结点开始, 搜索adjVex值为v的边结点, 代表边<u, v>, 若搜索

成功, 返回true, 否则返回false.

函数Insert(): 若输入的u, v无效, 则插入失败, 返回Failure. 否则从a[u]指示的边开始, 搜索adjVex值为v的边结点, 若不存在这样的边结

点, 则创建代表边<u, v>的新边结点, 并将其插在由指针a[u]所指示的单链表最前面, 并e++. 否则表示<u, v>是重复边, 返回Duplicate.

函数Remove(): 若输入的u, v无效, 则删除失败, 返回Failure. 否则从a[u]指示的边开始, 搜索adjVex值为v的边结点, 若存在这样的边, 删

除边, e--, 返回Success. 否则表示不存边<u, v>, 返回NotPresent.

实现代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
#include "stack"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
#include "string"
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
enum ResultCode { Underflow, Overflow, Success, Duplicate, NotPresent, Failure };
template <class T>
struct ENode
{
	ENode() { nxtArc = NULL; }
	ENode(int vertex, T weight, ENode *nxt) {
		adjVex = vertex;
		w = weight;
		nxtArc = nxt;
	}
	int adjVex;
	T w;
	ENode *nxtArc;
	/* data */
};
template <class T>
class Graph
{
public:
	virtual ~Graph() {}
	virtual ResultCode Insert(int u, int v, T &w) = 0;
	virtual ResultCode Remove(int u, int v) = 0;
	virtual bool Exist(int u, int v) const = 0;
	/* data */
};
template <class T>
class LGraph: public Graph<T>
{
public:
	LGraph(int mSize);
	~LGraph();
	ResultCode Insert(int u, int v, T &w);
	ResultCode Remove(int u, int v);
	bool Exist(int u, int v) const;
	int Vertices() const { return n; }
	void Output();
protected:
	ENode<T> **a;
	int n, e;
	/* data */
};
template <class T>
void LGraph<T>::Output()
{
	ENode<T> *q;
	for(int i = 0; i < n; ++i) {
		q = a[i];
		while(q) {
			cout << '(' << i << ' ' << q -> adjVex << ' ' << q -> w << ')';
			q = q -> nxtArc;
		}
		cout << endl;
	}
	cout << endl << endl;
}
template <class T>
LGraph<T>::LGraph(int mSize)
{
	n = mSize;
	e = 0;
	a = new ENode<T>*[n];
	for(int i = 0; i < n; ++i)
		a[i] = NULL;
}
template <class T>
LGraph<T>::~LGraph()
{
	ENode<T> *p, *q;
	for(int i = 0; i < n; ++i) {
		p = a[i];
		q = p;
		while(p) {
			p = p -> nxtArc;
			delete q;
			q = p;
		}
	}
	delete []a;
}
template <class T>
bool LGraph<T>::Exist(int u, int v) const
{
	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return false;
	ENode<T> *p = a[u];
	while(p && p -> adjVex != v) p = p -> nxtArc;
	if(!p) return false;
	return true;
}
template <class T>
ResultCode LGraph<T>::Insert(int u, int v, T &w)
{
	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
	if(Exist(u, v)) return Duplicate;
	ENode<T> *p = new ENode<T>(v, w, a[u]);
	a[u] = p;
	e++;
	return Success;
}
template <class T>
ResultCode LGraph<T>::Remove(int u, int v)
{
	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
	ENode<T> *p = a[u], *q = NULL;
	while(p && p -> adjVex != v) {
		q = p;
		p = p -> nxtArc;
	}
	if(!p) return NotPresent;
	if(q) q -> nxtArc = p -> nxtArc;
	else a[u] = p -> nxtArc;
	delete p;
	e--;
	return Success;
}
int main(int argc, char const *argv[])
{
	LGraph<int> lg(4);
	int w = 4; lg.Insert(1, 0, w); lg.Output();
	w = 5; lg.Insert(1, 2, w); lg.Output();
	w = 3; lg.Insert(2, 3, w); lg.Output();
	w = 1; lg.Insert(3, 0, w); lg.Output();
	w = 1; lg.Insert(3, 1, w); lg.Output();
	return 0;
}
时间: 2024-11-09 17:36:31

图的邻接表实现_LGraph的相关文章

浅谈数据结构之图的邻接表深度和广度优先遍历(九)

邻接矩阵是一种不错的图存储结构,但是我们发现,对于边数相对较少的图,这种结构是存在对存储空间的极大浪费的.我们知道,顺序存储结构存在预先分配内存可能造成空间浪费的问题,于是引出了链式存储的结构.同样的,我们也可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题.因此,对于图的存储结构,我们同样引入了一种数组与链表相组合的存储方法,我们一般称之为邻接表. 邻接表的处理方法是这样的:(1).图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易的读取顶点的信息,更加方便:另

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称

图的邻接表表示、广度优先、深度优先搜索

图,就是我们在数据结构中学到的图,它是一种存储信息的结构.图是一类在实际应用中非常常见的数据结构,当数据规模大到一定程度时,如何对其进行高效计算即成为迫切需要解决的问题.最常见的大规模图数据的例子就是互联网网页数据,网页之间通过链接指向形成规模超过500 亿节点的巨型网页图.再如,Facebook 社交网络也是规模巨大的图,仅好友关系已经形成超过10 亿节点.千亿边的巨型图,考虑到Facebook 正在将所有的实体数据节点都构建成网状结构,其最终形成的巨型网络数据规模可以想见其规模.要处理如此规

数据结构之---C语言实现图的邻接表存储表示

// 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME 3 // 顶点字符串的最大长度+1 #define MAX_VERTEX_NUM 20 typedef int InfoType; // 存放网的权值 typedef char VertexType[MAX_NAME]; // 字符串类型 typedef enum{DG, DN, AG

图(邻接表)

我们先来看一个图 我们想将这个图的信息存储到邻接表中,我们需要一个数组保存节点信息,还要有一个节点用来保存与该节点相邻的节点信息. 1 typedef struct arc_node 2 { 3 int pos; 4 int distance; 5 struct arc_node * next; 6 } Arc_node;//保存Node节点的相邻节点信息 7 8 typedef struct node 9 { 10 node_type info; 11 Arc_node * next; 12

数据结构(10) -- 图的邻接表存储

////////////////////////////////////////////////////////// //图的邻接表存储 ////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> using namespace std; //图的邻接表表示法 #define MaxVertexNum 100 enum GraphType{DG,

_DataStructure_C_Impl:图的邻接表存储

#include<stdio.h> #include<stdlib.h> #include<string.h> //图的邻接表类型定义 typedef char VertexType[4]; typedef char InfoPtr; typedef int VRType; #define INFINITY 10000 //定义一个无限大的值 #define MaxSize 50 //最大顶点个数 typedef enum{DG,DN,UG,UN}GraphKind;

基于C++ STL图的邻接表表示及深度、广度搜索实现

基于C++ STL图的邻接表表示及深度.广度搜索实现,对图论的学习有帮助,代码如下: #include <iostream> #include <vector> #include <set> using namespace std; #define MAX(a, b) ((a) > (b) ? (a) : (b) ) //定义图的定点 typedef struct Vertex { int id; vector<int> connectors; //存

看数据结构写代码(36) 图的邻接表表示与实现

图的邻接表表示法,是为每一个顶点建立一个链表,链表里存放着相同弧尾的 弧的信息,这些链表顺序存放在数组中.下面是无向图g2的邻接表 邻接表 比 邻接矩阵 节省空间,同时 也带来一些操作上的 不便,例如 看 两个顶点是否 相邻,需要 遍历 链表,在 求 无向图顶点的度时,只需 遍历 顶点的链表,而 求 有向图 顶点的度 需要 遍历 整个图 查找 弧头 为这个顶点的 个数. 如果 不想这样做,可以 建立 逆邻接表,即 链表里 存放着 相同 弧头的 弧 的信息. 下一节 要说的 十字链表 类似于这种结