The adjacency matrix needs to allocate space in advance, which is easy to cause a waste of space.
Moreover, when there is no edge between two vertices, the adjacency matrix cannot be solved.
The appearance of the adjacency list is a combination of the storage method of the array and the linked list (of course, it can also be a linked list + a linked list)
an adjacency list in the form of an array + a linked list.
A one-dimensional array is used to store vertex elements, and all the adjacent points of each vertex form a linear table
. :
The adjacency list is not unique.
If there are n vertices and e edges in the undirected graph, the adjacency list requires n head nodes and 2e table nodes. Suitable for storing sparse graphs
. The degree of vertex vi in an undirected graph is the number of nodes in the i-th singly linked list.
Features of adjacency list:
The out-degree of vertex vi is the number of nodes in the i-th singly-linked list. The
in-degree of vertex vi is the number of nodes in the entire singly-linked list whose adjacent point domain value is i-1.
Features of the inverse adjacency list:
The in-degree of
vertex vi is the number of nodes in the i-th singly-linked list. The out-degree of vertex vi is the number of nodes in the entire singly-linked list whose adjacent point domain value is i-1
Undirected graph implementation
#include<iostream>
using namespace std;
#define MAX 25
typedef char Vertype;
typedef int Edgetype;
typedef int Status;
typedef struct EdgeNode//边表结点 存放每个顶点的邻接点
{
int adjvex;//边表下标
Edgetype weight;//边表权重 若边不存在时即无NULL
struct EdgeNode *next;//指向下一个邻接点
}EdgeNode;
typedef struct VerNode//顶点表 存放顶点
{
Vertype data;//顶点元素
EdgeNode *firstedge;
}VerNode, AdjList[MAX];//邻接表的 顶点元素 和指向邻点的指针
typedef struct
{
AdjList adjList;//邻接表
int numVer,numEdge;//顶点数目和边的数目
}GraphAdjList;
Status CreatGraph(GraphAdjList &G)
{
int i, j, k;
Edgetype w;
EdgeNode *e;
cout << "Enter the number of vertices :"<< endl;
cin >> G.numVer;
cout << "Enter the number of Edges :" << endl;
cin >> G.numEdge;
cout << "Input vertex content :" << endl;
for (i = 0; i < G.numVer; i++)
{
cin >> G.adjList[i].data;//输入顶点元素
G.adjList[i].firstedge = NULL;//初始化邻边表为NULL;
}
for (k = 0; k < G.numEdge; k++)
{
cout <<"Enter the vertex number of the edge (Vi, Vj)" << endl;
cin >> i;
cin >> j;
cout << "Enter the weight of edge" << i << "-" << j << endl;
cin >> w;
e = new EdgeNode;//将两个顶点相结即可。
e->adjvex = j;// 邻接序号为j
e->next = G.adjList[i].firstedge;//i的第一个邻接指针 为e的指针
e->weight = w;
G.adjList[i].firstedge = e;
//有向图则只有生成一次即可
e = new EdgeNode;
e->adjvex = i;//无向图 重复一遍
e->next = G.adjList[j].firstedge;
G.adjList[j].firstedge = e;
e->weight = w;
}
return 0;
}
//输出无向图
Status DispGraph(GraphAdjList &G)
{
int i, j, k;
cout <<"Output element of ver" << endl;
for (i = 0; i < G.numVer; i++)
{
cout << G.adjList[i].data << '\t';
}
cout << "Output weight"<< endl;
for (k = 0; k < G.numVer; k++)
{
EdgeNode *p = G.adjList[k].firstedge;//中间指针
cout <<"xaibiao"<< k <<"constent"<< G.adjList[k].data << "jiedian:" << endl;
while (p != NULL)
{
cout <<G.adjList[k].data<< "->" << p->adjvex << '\t' << p->weight << '\t' << endl;
p = p->next;
}
}
/*
for (k = 0; k < G.numEdge; k++)
{
//cout << G.adjList[k].firstedge->adjvex << '\t' << G.adjList[k].firstedge->weight << '\t'<<G.adjList[k].firstedge->next->adjvex<<endl;
cout << G.adjList[k].firstedge->weight << '\t';
}
*/
return 0;
}
//返回一个顶点的位置 和其邻接表内容
Status OutGraph_x(GraphAdjList &G)
{
cout <<"请输入需要找的顶点内容: " << endl;
Vertype x;
cin >> x;
for (int i = 0; i < G.numVer; i++)
{
if(G.adjList[i].data == x)
{
cout << "该元素在图中的位置为: " <<i<<"。 相关邻接表为"<<endl;
EdgeNode *p = G.adjList[i].firstedge;
while (p != NULL)
{
cout << p->adjvex << '\t' << p->weight << '\t' << endl;
p = p->next;
}
}
}
return 0;
}
//新增一个顶点和对应边
Status AddGraph_x(GraphAdjList &G)
{
Vertype x;
Edgetype edg_num;
int w;
int i;
EdgeNode *p;
if (G.numVer >= MAX)
{
cout << "Graph memory is full and cannot be expanded "<< endl;
return NULL;
}
else
{
cout << "请输入需要插入的新顶点内容: " << endl;
cin >> x;
G.numVer++;
G.adjList[G.numVer - 1].data = x;//顶点内容赋值
G.adjList[G.numVer - 1].firstedge = NULL;//顶点指针NULL初始化
cout << "Please enter the number of new edges" << endl;//新增边的数目
//如果不成边呢
cin >> edg_num;
G.numEdge = G.numEdge+ edg_num;
p = new EdgeNode;
for (int j = 0; j < edg_num; j++)
{
cout << "请输入与其成边的顶点位置" << endl;
cin >> i;
cout << "请输入权重" << endl;
cin >> w;
/*while (p != NULL)
{
p = p->next;//找到最后一个结点为空时
}*/
//p = new EdgeNode;
p->adjvex = G.numVer - 1;
p->next = G.adjList[i].firstedge;
G.adjList[i].firstedge = p;
p->weight = w;
//p = new EdgeNode;
p->adjvex = i;
p->next = G.adjList[G.numVer - 1].firstedge;
G.adjList[G.numVer - 1].firstedge = p;
p->weight = w;
}
}
return 0;
}
//删除一个顶点
Status DelGraph_x(GraphAdjList &G)
{
Vertype x;
cout <<"请输入需要删除的顶点:" << endl;
cin >> x;
for (int i = 0; i < G.numVer; i++)
{
if (G.adjList[i].data == x)
{
G.adjList[i].data = NULL;//因为是数组类型 其结构必定存在 所以将其置为空
//free((void *)G.adjList[i].data); //释放顶点
G.adjList[i].firstedge=NULL;
}
}
return 0;
}
int main()
{
GraphAdjList G;
CreatGraph(G);
DispGraph(G);
OutGraph_x(G);
AddGraph_x(G);
DispGraph(G);
DelGraph_x(G);
DispGraph(G);
return 0;
}
Realization of directed graph
#include<iostream>
using namespace std;
#define MAX 25
typedef char Vertype;
typedef int Edgetype;
typedef int Status;
typedef struct EdgeNode//边表结点 存放每个顶点的邻接点
{
int adjvex;//边表下标
Edgetype weight;//边表权重 若边不存在时即无NULL
struct EdgeNode *next;//指向下一个邻接点
}EdgeNode;
typedef struct VerNode//顶点表 存放顶点
{
Vertype data;//顶点元素
EdgeNode *firstedge;
}VerNode, AdjList[MAX];//邻接表的 顶点元素 和指向邻点的指针
typedef struct
{
AdjList adjList;//邻接表
int numVer, numEdge;//顶点数目和边的数目
}GraphAdjList;
Status CreatGraph(GraphAdjList &G)
{
int i, j, k;
Edgetype w;
EdgeNode *e;
cout << "Enter the number of vertices :" << endl;
cin >> G.numVer;
cout << "Enter the number of Edges :" << endl;
cin >> G.numEdge;
cout << "Input vertex content :" << endl;
for (i = 0; i < G.numVer; i++)
{
cin >> G.adjList[i].data;//输入顶点元素
G.adjList[i].firstedge = NULL;//初始化邻边表为NULL;
}
for (k = 0; k < G.numEdge; k++)
{
cout << "Enter the vertex number of the edge (Vi->Vj)" << endl;
cin >> i;
cin >> j;
cout << "Enter the weight of edge" << i << "-" << j << endl;
cin >> w;
e = new EdgeNode;//将两个顶点相结即可。
e->adjvex = j;// 邻接序号为j
e->next = G.adjList[i].firstedge;//i的第一个邻接指针 为e的指针
e->weight = w;
G.adjList[i].firstedge = e;
//有向图则只有生成一次即可
/*
e = new EdgeNode;
e->adjvex = i;//无向图 重复一遍
e->next = G.adjList[j].firstedge;
G.adjList[j].firstedge = e;
e->weight = w;*/
}
return 0;
}
Status DispGraph(GraphAdjList &G)
{
int i, j, k;
cout << "Output element of ver" << endl;
for (i = 0; i < G.numVer; i++)
{
cout << G.adjList[i].data << '\t';
}
cout << "Output weight" << endl;
for (k = 0; k < G.numVer; k++)
{
EdgeNode *p = G.adjList[k].firstedge;//中间指针
cout << "xaibiao" << k << "constent" << G.adjList[k].data << "jiedian:" << endl;
while (p != NULL)
{
cout << G.adjList[k].data << "->" << p->adjvex << '\t' << p->weight << '\t' << endl;
p = p->next;
}
}
return 0;
}
int main()
{
GraphAdjList G;
CreatGraph(G);
DispGraph(G);
return 0;
}