二、已知一个有向图如下图所示,试给出图的邻接矩阵和邻接表存储示意图(画图,分别用矩阵和数组链表图表示),并编程分别实现该图的邻接矩阵表示和邻接表表示,要求编写两种表示方法的存储结构、相关基本操作,并在主函数中创建该图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pUltTK0z-1612100075928)(图2.assets/clip_image002.jpg)]
有向图的邻接矩阵表示
#include <iostream>
#define maxValue max
#define E 50
#define V 10
using namespace std;
typedef char V_data;//存储数据类型
typedef struct{
V_data vexlist[V];//顶点集
int edge[E][E];//矩阵表
int n,e;//矩阵的边数,顶点数目
}MTGraph;
void CreateMGraph(MTGraph *G){
int i,j;
//输入图的边数和点数
cout<<"please cin the mount of point and edge:";
cin>>G->n;
cin>>G->e;
//输入顶点信息
cout<<"please cin the information of each point:";
for(i=0;i<G->n;i++){
cin>>G->vexlist[i];
}
//邻接矩阵初始化
for(i=0;i<G->n;i++){
for(j=0;j<G->n;j++){
G->edge[i][j]=0;
}
}
//输入图中边的节点(i,j),此处权值为1,这里和无向图不一样
cout<<"please cin position_info of each point:";
for(int k=0;k<G->e;k++) {
cin>>i;
cin>>j;
G->edge[i-1][j-1] =1;
}
}
MTGraph NewNode(MTGraph *G,char x){
G->vexlist[G->n] =x;
for(int i=0;i<=G->n;i++){
G->edge[G->n][i]=0;
G->edge[i][G->n]=0;
}
++G->n;
return *G;
}
void delNode(MTGraph *G,char x){
//遍历点的数据,如有有执行删除操作
for(int i=0;i<G->n;i++){
if(G->vexlist[i] == x){
cout<<"find "<<x<<endl;
//删除顶点集
for(int j=i;j<G->n-1;j++){
G->vexlist[j] =G->vexlist[j+1];
}
G->vexlist[G->n-1] =0;
cout<<"already del point! "<<x<<endl;
//删除边集
for(int ins=i;ins<G->n;ins++){
if(ins==G->n-1){
for(int k=0;k<G->n;k++){
G->edge[ins][k] =0;
G->edge[k][ins] =0;
}
}
for(int k=0;k<G->n;k++){
G->edge[ins][k] =G->edge[ins+1][k];
G->edge[k][ins] =G->edge[k][ins+1];
}
G->edge[ins][ins]=G->edge[ins+1][ins+1];
}
//点的数量减一
--G->n;
break;
}
if(i=G->n)
cout<<"not find "<<x<<endl;
}
}
void setSucc(MTGraph *G,char x1,char x2){
int i,j;
for(int k=0;k<G->n;k++){
if(G->vexlist[k] ==x1){
i=k;
}
if(G->vexlist[k] ==x2){
j=k;
}
}
G->edge[i][j] =1;//有向图,建立一条边
}
void delSucc(MTGraph *G,char x1,char x2){
int i,j;
for(int k=0;k<G->n;k++){
if(G->vexlist[k] ==x1){
i=k;
}
if(G->vexlist[k] ==x2){
j=k;
}
}
G->edge[i][j] =0;
}
void print(MTGraph *G){
cout<<"all information of the graph:\n ";
int i,j;
for(i=0;i<G->n;i++){
cout<<G->vexlist[i]<<" ";
}
cout<<endl;
for(i=0;i<G->n;i++){
cout<<G->vexlist[i]<<" ";
for(j=0;j<G->n;j++){
cout<<G->edge[i][j]<<" ";
}
cout<<endl;
}
}
int main(){
MTGraph *G1 =new MTGraph();
CreateMGraph(G1);
print(G1);
cout<<"add element 8:\n";
NewNode(G1,'8');
print(G1);
cout<<"delete element 1:\n";
delNode(G1,'1');
print(G1);
cout<<"add edge between 2 and 6\n";
setSucc(G1,'2','8');
print(G1);
return 0;
}
有向图的邻接表表示
#include <iostream>
using namespace std;
#define NumVertices 11 //顶点个数
typedef char VertexData; //顶点数据类型
typedef int EdgeData; //边上权值类型
typedef struct node { //边表结点
int adjvex; //邻接点域(下标)
//EdgeData cost; //边上的权值
struct node *next; //下一边链接指针
} EdgeNode;
typedef struct { //顶点表结点
VertexData vertex; //顶点数据域
EdgeNode * firstedge; //边链表头指针
} VertexNode;
typedef struct { //图的邻接表
VertexNode vexlist [NumVertices];
int n, e; //图中当前的顶点个数与边数
} AdjGraph;
void CreateGraph (AdjGraph *G) {
cout<<"输入顶点个数和边数:";
cin >> G->n >> G->e; //1.输入顶点个数和边数
int i;
int head,tail;
cout<<"输入顶点信息:";
for ( i = 1; i <= G->n; i++) { //2.建立顶点表
cin >> G->vexlist[i].vertex; //2.1输入顶点信息
G->vexlist[i].firstedge = NULL;
} //2.2边表置为空表
//有向图和无向图不同
cout<<"逐条边输入,建立边表:\n";
for ( i = 1; i <= G->e; i++) { //3.逐条边输入,建立边表
cin >> tail >> head; //3.1输入(变量说明省了)
EdgeNode * p = new EdgeNode; //3.2建立边结点
p->adjvex = head;
p->next = G->vexlist[tail].firstedge; //3.4链入第tail 号链表的前端
G->vexlist[tail].firstedge = p;
}
} //时间复杂度:O(2e+n)
void print(AdjGraph *G){
for(int i=1;i<=G->n;i++){
cout<<G->vexlist[i].vertex<<"-->";
EdgeNode *temp =G->vexlist[i].firstedge;
while(temp!=NULL){
cout<<temp->adjvex<<"-->";
//G->vexlist[i].firstedge =G->vexlist[i].firstedge->next;
temp=temp->next;
}
cout<<"NULL\n";
}
}
int main(){
AdjGraph *g =new AdjGraph();
CreateGraph(g);
print(g);
return 0;
}