# 图——基本的图算法（一）图的存储结构

## 2. 图的各种存储结构及实现

### 2.1 邻接矩阵

（1）总体思路

（2）具体实现
A. 数据结构

#define Maximum 1000
typedef int VexType;

VexType vertexlist[Maximum];


#define Maximum 1000
typedef int MatrixType;

MatrixType matrix[Maximum][Maximum];


#define Maximum 1000
typedef int VexType;
typedef int MatrixType;

VexType vertexlist[Maximum];
MatrixType matrix[Maximum][Maximum];
int vertexnumber;
int edgenumber;
};


B. 图的创建

a. 顶点表初始化：

CreateVertexlist() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
cin>>i;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
G->vertexlist[j] = k;
}
}


b. 邻接矩阵初始化

 CreateMatrix() {
int i, j, k, s, e, w;
cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
G->matrix[s][e] = w;
}
}



c. 图的创建

CreateGraph() {
CreateVertexlist();
CreateMatrix();
}


C. 针对有向图和无向图分别写一个类，对上述内容进行封装：
a. class UndirectGraph（无向图）

#define Maximum 1000
typedef int VexType;
typedef int MatrixType;

VexType vertexlist[Maximum];
MatrixType matrix[Maximum][Maximum];
int vertexnumber;
int edgenumber;
};

class UndirectGraph {
public:

UndirectGraph() {
memset(G->vertexlist, 0, sizeof(G->vertexlist));
memset(G->matrix, 0, sizeof(G->matrix));
}

CreateVertexlist() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
cin>>i;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
G->vertexlist[j] = k;
}
}

CreateMatrix() {
int i, j, k, s, e, w;
cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
G->matrix[s][e] = w;
G->matrix[e][s] = w;
}
}

CreateGraph() {
CreateVertexlist();
CreateMatrix();
}

};


b. class DirectGraph（无向图）

#define Maximum 1000
typedef int VexType;
typedef int MatrixType;

VexType vertexlist[Maximum];
MatrixType matrix[Maximum][Maximum];
int vertexnumber;
int edgenumber;
};

class DirectGraph {
public:

DirectGraph() {
memset(G->vertexlist, 0, sizeof(G->vertexlist));
memset(G->matrix, 0, sizeof(G->matrix));
}

CreateVertexlist() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
cin>>i;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
G->vertexlist[j] = k;
}
}

CreateMatrix() {
int i, j, k, s, e, w;
cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w; //s:边的起点  e:边的终点  w:边的权值
G->matrix[s][e] = w;
}
}

CreateGraph() {
CreateVertexlist();
CreateMatrix();
}

};


### 2.2 邻接链表

（1）总体思路

（2）具体实现
A. 数据结构

typedef struct EdgeListNode{
int weight;
EdgeListNode* next;
};


typedef struct VertexListNode{
int data;
};


#define Maximum 1000 //预设一个边表大小的最大值
int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};


#define Maximum 1000

typedef struct EdgeListNode{
int weight;
EdgeListNode* next;
};

typedef struct VertexListNode{
int data;
};

int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};


B. 图的创建

a. 顶点表初始化：

void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl; //输入顶点个数
cin>>i;
G->vertexnumber = i; //设置图结构里的顶点个数
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) { //依此输入每个顶点，且该顶点再顶点表中对应的下标为i
cin>>k;
k = G->vertextlist[i].data;
}
}


b. 创建边表

void EdgeListCreate() {
int i, j, s, e, w;
EdgeListNode* edge;
cout<<"Please enter the number of edges"<<endl; //输入边的条数
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w; //s:边的起点  e:边的终点  w:边的权值
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->weight = w;
/*此处采用头插法，即每次往边表的头部插入新结点*/

edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->weight = w;
}
}


void EdgeListCreate() {
int i, j, s, e, w;
EdgeListNode* edge;
cout<<"Please enter the number of edges"<<endl; //输入边的条数
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w; //s:边的起点  e:边的终点  w:边的权重
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->weight = w;
/*此处采用头插法，即每次往边表的头部插入新结点*/
}
}


c. 综合起来，图的创建：

void CreateGraphAdjList() {
VertexListInit();
EdgeListCreate();
}


C. 针对有向图和无向图分别写一个类，对上述内容进行封装：
a. class UndirectGraph（无向图）

#define Maximum 1000

typedef struct EdgeListNode{
int weight;
EdgeListNode* next;
};

typedef struct VertexListNode{
int data;
};

int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};

class UndirectGraph {
public:

UndirectGraph() {
}

void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
cin>>i;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
G->vertextlist[i].data = k;
}
}

void EdgeListCreate() {
int i, j, s, e, w;
EdgeListNode* edge;
cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->weight = w;

edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->weight = w;
}
}

VertexListInit();
EdgeListCreate();
}

};



b. class DirectGraph（有向图）

#define Maximum 1000

typedef struct EdgeListNode{
int weight;
EdgeListNode* next;
};

typedef struct VertexListNode{
int data;
};

int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};

class DirectGraph {
public:

DirectGraph() {
}

void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
cin>>i;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
G->vertextlist[i].data = k;
}
}

void EdgeListCreate() {
int i, j, s, e, w;
EdgeListNode* edge;
cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->weight = w;
}
}

VertexListInit();
EdgeListCreate();
}

};


### 2.3 十字链表（针对有向图邻接链表的优化）

（1）总体思路

（2）具体实现
A. 数据结构
a. 顶点表中结点的结构：

typedef struct VertexListNode{
int data;
};


b. 边表中结点的结构：

typedef struct EdgeListNode{
int tailvex;
int weight;
};


c. 用十字链表表示的图结构：

typedef struct GraphOthList{
int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};


B. 图的创建
a. 初始化顶点表

void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
k = G->vertextlist[j].data;
}
}


b. 初始化边表

  void EdgeListCreate() {
int i, j, s, e, w;

cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;  //s:弧的起点  e:弧的终点  w:弧的权值
EdgeListNode* edge;
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->tailvex = e;
//指向弧起点的出边表中的下一个结点，采用头插法

//指向弧终点的入边表中的下一个结点，采用头插法
}

}


c. 综合起来，图的创建：

void CreateGraph() {
VertexListInit();
EdgeListCreate();
}


C. 把上述内容封装起来，创建一个十字链表表示图的类：

#define Maximum 1000

typedef struct EdgeListNode{
int tailvex;
};

typedef struct VertexListNode{
int data;
};

typedef struct GraphOthList{
int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};

class DirectGraph {
public:
GraphOthList* G;

DirectGraph() {
G = (GraphOthList*)malloc(sizeof(GraphOthList));
}

void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
k = G->vertextlist[j].data;
}
}

void EdgeListCreate() {
int i, j, s, e, w;

cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
EdgeListNode* edge;
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->tailvex = e;
}

}

void CreateGraph() {
VertexListInit();
EdgeListCreate();
}

};


（3）实际示例

### 2.4 邻接多重表（针对无向图邻接链表的优化）

（1）总体思想

（2）具体实现
A. 数据结构
a. 顶点表中结点的结构：

typedef struct VertexListNode{
int data;
EdgeListNode* firstedge;
};


b. 边表中结点的结构：

typedef struct EdgeListNode{
int ivex;
int jvex;
int weight;
};


c. 用邻接多重表表示的图结构：

typedef struct GraphMultiAdjList{
int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};


B. 图的创建
a. 初始化顶点表

 void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
k = G->vertextlist[j].data;
G->vertextlist[j].firstedge = NULL;
}
}


b. 初始化边表

    void EdgeListCreate() {
int i, j, k, s, e, w;

cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
EdgeListNode* edge;
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->ivex = s;
edge->jvex = e;
edge->weight = w;
/*G->vertextlist[s]里的结点表示的边都以s为其中一个顶点*/
/*当前这条边也是以s为其中一个顶点的，因此可以让G->vertextlist[s].firstedge指向它*/
G->vertextlist[s].firstedge = edge;
/*G->vertextlist[e]里的结点表示的边都以e为其中一个顶点*/
/*当前这条边也是以e为其中一个顶点的，因此可以让G->vertextlist[e].firstedge指向它*/
G->vertextlist[e].firstedge = edge;

}
}


c. 综合起来，图的创建：

void CreateGraph() {
VertexListInit();
EdgeListCreate();
}


C. 把上述内容封装起来，创建一个多重邻接表表示图的类：

#define Maximum 1000

typedef struct EdgeListNode{
int ivex;
int jvex;
int weight;
};

typedef struct VertexListNode{
int data;
EdgeListNode* firstedge;
};

int vertexnumber;
int edgenumber;
VertexListNode vertextlist[Maximum];
};

class DirectGraph {
public:

DirectGraph() {
}

void VertexListInit() {
int i, j, k;
cout<<"Please enter the number of vertexes"<<endl;
G->vertexnumber = i;
cout<<"Please enter the data of each vertex in term"<<endl;
for(j=0; j<i; j++) {
cin>>k;
k = G->vertextlist[j].data;
G->vertextlist[j].firstedge = NULL;
}
}

void EdgeListCreate() {
int i, j, k, s, e, w;

cout<<"Please enter the number of edges"<<endl;
cin>>i;
G->edgenumber = i;
cout<<"Please enter the information of each edge in term"<<endl;
for(j=0; j<i; j++) {
cin>>s>>e>>w;
if(s > e) {
k = s;
s = e;
e = k;
}
EdgeListNode* edge;
edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));
edge->ivex = s;
edge->jvex = e;
edge->weight = w;
G->vertextlist[s].firstedge = edge;
G->vertextlist[e].firstedge = edge;

}

}

void CreateGraph() {
VertexListInit();
EdgeListCreate();
}

};


### 2.5 边集数组

（1）基本思想

（2）数据结构
a. 顶点数组：

int vertexlist[Maximum]; //存放每个顶点的权值


b. 边数组里每一项的结构：

typedef struct EdgeArrayNode{
int startvertex; //起点下标
int endvertex; //终点下标
int weight; //边的权值
};


c. 用边集数组表示的图的结构：

typedef struct GraphEdgeArray {
int vertexnumber; //顶点数
int edgenumber; //边数
int vertexlist[Maximum];
EdgeArrayNode edgearray[Maximum*Maximum];
};


（3）实际例子

• 点赞 9
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏 24
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

hh66__66hh

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文
10-23
10-23 2423

02-27 3241
10-28 2359
02-27 6245
03-30 751
05-15 65
08-18 1万+
02-07 1万+
02-07 1007