大家直接看我在wolai写的这篇邻接表的,下面文章是凑字数滴。图也放不出来
(wolai是个好软件,首月开会员还免费,大家都快去用它,不打广)
邻接表的定义
- **邻接表(Adjacency List)**是图的一种顺序存储与链式存储结合的存储方法。
- 对于图G中的每个顶点Vi,将所有邻接于Vi的顶点Vj链成一个单链表,这个单链表就称为顶点Vi的邻接表,再将所有顶点的邻接表表头放到数组中,就构成了图的邻接表。
- 在邻接表表示中,包括两种结点结构。
- 一个是顶点结点,每个顶点结点由2个域组成,其中data域存储顶点Vi的名或其相关信息,firstArc指向顶点Vi的第一个邻接点的边结点;-
- 第二个是边结点,边结点由3个域组成。其中abjVex域存放与Vi邻接的点的序号,nextArc指向Vi下一个邻接点的边结点,info域存储和边或弧相关的信息,如权值,如图
为什么要使用邻接表
当图中的边数相对于顶点较少时,邻接矩阵是对存储空间的极大浪费。我们可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题。使用树结构的孩子表示法,将结点存入数组,并对结点的孩子进行链式存储,不管有多少孩子,也不会存在空间浪费问题。
如果想知道某个顶点的度,就去查找这个顶点的边表中结点的个数。若要判断顶点vi和vj是否存在边,只需要测试顶点vi的边表adjvex中是否存在结点vj的下标就行了 我们很容易就可以算出某个顶点的入度或出度是多少,判断两顶点是否存在弧也很容易实现。
对于带权值的图,可以在边结点定义中再增加一个weight的数据域,存储权值信息即可
- 有向图的代码实现(点击展开)
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
#define MAX 100
class ListDG {
private:
class ENode {
public:
int ivex;
ENode* nextEdge;
};
// 邻接表中表的顶点
class VNode {
public:
char data;
ENode* firstEdge;
};
private: // 私有成员
int mVexNum;
int mEdgNum;
VNode mVexs[MAX];
public:
ListDG();
ListDG(char vexs[], int vlen, char edges[][2], int elen);
~ListDG();
void print();
private:
char readChar();
int getPosition(char ch);
void linkLast(ENode* list, ENode* node);
};
ListDG::ListDG() {
char c1, c2;
int v, e;
int i, p1, p2;
ENode* node1, * node2;
cout << "input vertex number: ";
cin >> mVexNum;
cout << "input edge number: ";
cin >> mEdgNum;
if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))) {
cout << "input error: invalid parameters! " << endl;
return;
}
for (i = 0; i < mVexNum; ++i) {
cout << "vertex(" << i << "):";
mVexs[i].data = readChar();
mVexs[i].firstEdge = nullptr;
}
for (i = 0; i < mEdgNum; ++i) {
cout << "edge(" << i << "):";
c1 = readChar();
c2 = readChar();
p1 = getPosition(c1);
p2 = getPosition(c2);
// 初始化node1
node1 = new ENode();
node1->ivex = p2;
if (mVexs[p1].firstEdge == nullptr)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
}
}
ListDG::ListDG(char vexs[], int vlen, char edges[][2], int elen) {
char c1, c2;
int i, p1, p2;
ENode* node1, * node2;
mVexNum = vlen;
mEdgNum = elen;
for (i = 0; i < mVexNum; i++)
{
mVexs[i].data = vexs[i];
mVexs[i].firstEdge = NULL;
}
for (i = 0; i < mEdgNum; ++i) {
c2 = edges[i][1];
p1 = getPosition(c1);
p2 = getPosition(c2);
// 初始化node1
node1 = new ENode();
node1->ivex = p2;
if (mVexs[p1].firstEdge == nullptr)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
}
}
ListDG::~ListDG() {
}
void ListDG::linkLast(ENode* list, ENode* node) {
ENode* p = list;
while (p->nextEdge)
p = p->nextEdge;
p->nextEdge = node;
}
int ListDG::getPosition(char ch) {
int i;
for (i = 0; i < mVexNum; ++i)
if (mVexs[i].data == ch)
return i;
return -1;
}
char ListDG::readChar() {
char ch;
do {
cin >> ch;
} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
return ch;
}
void ListDG::print() {
int i, j;
ENode* node;
cout << "List Graph: " << endl;
for (i = 0; i < mVexNum; ++i) {
cout << i << "(" << mVexs[i].data << "):";
node = mVexs[i].firstEdge;
while (node != nullptr) {
cout << node->ivex << "(" << mVexs[node->ivex].data << ") ";
node = node->nextEdge;
}
cout << endl;
}
}
int main() {
char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
char edges[][2] = {
{'A', 'B'},
{'B', 'C'},
{'B', 'E'},
{'B', 'F'},
{'C', 'E'},
{'D', 'C'},
{'E', 'B'},
{'E', 'D'},
{'F', 'G'}
};
int vlen = sizeof(vexs) / sizeof(vexs[0]);
int elen = sizeof(edges) / sizeof(edges[0]);
ListDG* pG;
pG = new ListDG(vexs, vlen, edges, elen);
pG->print();
return 0;
}
- 无向图的代码实现(点击展开)
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
constexpr auto MAX = 100;
class ListUDG {
private:
class ENode {
public:
int ivex;
ENode* nextEdge;
};
class VNode {
public:
char data;
ENode* firstEdge;
};
private:
int mVexNum;
int mEdgNum;
VNode mVexs[MAX];
public:
ListUDG();
ListUDG(char vexs[], int vlen, char edges[][2], int elen);
~ListUDG();
void print();
private:
char readChar();
int getPosition(char ch);
void linkLast(ENode* list, ENode* node);
};
ListUDG::ListUDG() {
char c1, c2;
int i, p1, p2;
ENode* node1, * node2;
cout << "input vertex number: ";
cin >> mVexNum;
cout << "input edge number: ";
cin >> mEdgNum;
if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))) {
cout << "input error: invalid parameters!" << endl;
return;
}
for (i = 0; i < mVexNum; ++i) {
cout << "vertex(" << i << "):";
mVexs[i].data = readChar();
mVexs[i].firstEdge = nullptr;
}
for (i = 0; i < mEdgNum; ++i) {
cout << "edge(" << i << "):";
c1 = readChar();
c2 = readChar();
p1 = getPosition(c1);
p2 = getPosition(c2);
node1 = new ENode();
node1->ivex = p2;
if (mVexs[p1].firstEdge == nullptr)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
node2 = new ENode();
node2->ivex = p1;
if (mVexs[p2].firstEdge == nullptr)
mVexs[p2].firstEdge = node2;
else
linkLast(mVexs[p2].firstEdge, node2);
}
}
ListUDG::ListUDG(char vexs[], int vlen, char edges[][2], int elen) {
char c1, c2;
int i, p1, p2;
ENode* node1, * node2;
mVexNum = vlen;
mEdgNum = elen;
for (i = 0; i < mVexNum; ++i) {
mVexs[i].data = vexs[i];
mVexs[i].firstEdge = nullptr;
}
for (i = 0; i < mEdgNum; ++i) {
c1 = edges[i][0];
c2 = edges[i][1];
p1 = getPosition(c1);
p2 = getPosition(c2);
node1 = new ENode();
node1->ivex = p2;
if (mVexs[p1].firstEdge == nullptr)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
node2 = new ENode();
node2->ivex = p1;
if (mVexs[p2].firstEdge == nullptr)
mVexs[p2].firstEdge = node2;
else
linkLast(mVexs[p2].firstEdge, node2);
}
}
ListUDG::~ListUDG() {
}
void ListUDG::linkLast(ENode* list, ENode* node) {
ENode* p = list;
while (p->nextEdge)
p = p->nextEdge;
p->nextEdge = node;
}
int ListUDG::getPosition(char ch) {
int i;
for (i = 0; i < mVexNum; ++i)
if (mVexs[i].data == ch)
return i;
return -1;
}
char ListUDG::readChar() {
char ch;
do {
cin >> ch;
} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
return ch;
}
void ListUDG::print() {
int i, j;
ENode* node;
cout << "List Graph:" << endl;
for (i = 0; i < mVexNum; ++i) {
cout << i << "(" << mVexs[i].data << ")";
node = mVexs[i].firstEdge;
while (node != nullptr) {
cout << node->ivex << "(" << mVexs[node->ivex].data << ")";
node = node->nextEdge;
}
cout << endl;
}
}
int main(){
char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
char edges[][2] = {
{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'F', 'G'} };
int vlen = sizeof(vexs) / sizeof(vexs[0]);
int elen = sizeof(edges) / sizeof(edges[0]);
ListUDG* pG;
pG = new ListUDG(vexs, vlen, edges, elen);
pG->print();
return 0;
}