// Graph_Adjacency List.cpp : Defines the entry point for the console application.
/*-----CODE FOR FUN---------------
-------CREATED BY Dream_Whui------
-------2015-2-12--------------------*/
#include "stdafx.h"
#include <iostream>
#include <queue>
using namespace std;
#define MAX_VERTEX_NUM 20
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef char* VertexType;
typedef int InfoType;
typedef enum
{
DG,DN,UDG,UDN//有向图,有向网,无向图,无向网
}GraphKind;
typedef struct ArcNode
{
int adjvex; //该弧所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条弧的指针
InfoType *info; //该弧相关信息的指针
}ArcNode;
typedef struct VNode
{
VertexType data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的弧的指针
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum,arcnum; //顶点数,弧数
int kind; //图的种类标记
}ALGraph;
bool visited[MAX_VERTEX_NUM];
int CreateDG(ALGraph &G);//构造有向图
int CreateDN(ALGraph &G);//构造有向网
int CreateUDG(ALGraph &G);//构造无向图
int CreateUDN(ALGraph &G);//构造无向网
int CreateGraph(ALGraph &G)//采用邻接表表示法,构造图G
{
int n;
cout<<"创建有向图(0),有向网(1),无向图(2),无向网(3)"<<endl;
cin>>n;
switch(n)
{
case DG:
G.kind = DG;
return CreateDG(G);//有向图
case DN:
G.kind = DN;
return CreateDN(G);//有向网
case UDG:
G.kind = UDG;
return CreateUDG(G);//无向图
case UDN:
G.kind = UDN;
return CreateUDN(G);//无向网
default:
return ERROR;
}
}
int LocateVex(ALGraph G, VertexType v) //顶点v在图中的位置
{
int i;
for(i=0; i<G.vexnum; i++)
{
if(strcmp(G.vertices[i].data,v)==0)
return i;
}
return -1;
}
void CreateSub(ALGraph &G, int i, int j, int* w)//创建图(网)的辅助函数,构建第i个顶点到第j个顶点,权值w
{
ArcNode *e, *p, *pre;
e = (ArcNode*)malloc(sizeof(ArcNode));
p = (ArcNode*)malloc(sizeof(ArcNode));
pre = (ArcNode*)malloc(sizeof(ArcNode));
e->adjvex = j; //
e->nextarc = NULL;
e->info = w;
if(!G.vertices[i].firstarc) //在头结点后插入
G.vertices[i].firstarc = e;
else
{
p = G.vertices[i].firstarc;
if(p->adjvex < j) //在第一个结点前插入(第一个结点指头结点后面的那个结点)
{
e->nextarc = p;
G.vertices[i].firstarc = e;
}
else //在第以个结点后插入
{
pre = p;
p = p->nextarc;
while(p)
{
if(p->adjvex < j)
{
e->nextarc = p;
pre->nextarc = e;
break;
}
pre = p;
p = p->nextarc;
}
if(!p) //在尾结点后插入
pre->nextarc = e;
}
}
}
int CreateDG(ALGraph &G)//构造有向图
{
cout<<"输入顶点数,边数:"<<endl;
cin>>G.vexnum>>G.arcnum;
int i,j,k,w;
for(i=0; i<G.vexnum; i++)//构造顶点向量
{
cout<<"输入第"<<i+1<<"个顶点的名称:";
G.vertices[i].data = (VertexType)malloc( sizeof(char) );
cin>>G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
char *v1, *v2;
v1 = (char*)malloc(sizeof(char));
v2 = (char*)malloc(sizeof(char));
for(k=0; k<G.arcnum; k++)
{
cout<<"输入相连的边(v1,v2):";
cin>>v1>>v2;
i = LocateVex(G,v1);//弧尾
j = LocateVex(G,v2);//弧头
w = 1;
CreateSub(G,i,j,&w);
}
G.kind = DG;
return OK;
}
int CreateUDG(ALGraph &G)//构造无向图
{
cout<<"输入顶点数,边数:"<<endl;
cin>>G.vexnum>>G.arcnum;
int i,j,k,w;
for(i=0; i<G.vexnum; i++)//构造顶点向量
{
cout<<"输入第"<<i+1<<"个顶点的名称:";
G.vertices[i].data = (VertexType)malloc( sizeof(char) );
cin>>G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
char *v1, *v2;
v1 = (char*)malloc(sizeof(char));
v2 = (char*)malloc(sizeof(char));
for(k=0; k<G.arcnum; k++)
{
cout<<"输入相连的边(v1,v2):";
cin>>v1>>v2;
i = LocateVex(G,v1);//边的起点
j = LocateVex(G,v2);//边的终点
CreateSub(G,i,j,&w);
CreateSub(G,j,i,&w);
}
G.kind = UDG;
return OK;
}
int CreateDN(ALGraph &G)//构造有向网
{
cout<<"输入顶点数,边数:"<<endl;
cin>>G.vexnum>>G.arcnum;
int i,j,k,w;
for(i=0; i<G.vexnum; i++)//构造顶点向量
{
cout<<"输入第"<<i+1<<"个顶点的名称:";
G.vertices[i].data = (VertexType)malloc( sizeof(char) );
cin>>G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
char *v1, *v2;
v1 = (char*)malloc(sizeof(char));
v2 = (char*)malloc(sizeof(char));
for(k=0; k<G.arcnum; k++)
{
cout<<"输入相连的边及权值(v1,v2,w):";
cin>>v1>>v2>>w;
i = LocateVex(G,v1);//弧尾
j = LocateVex(G,v2);//弧头
CreateSub(G,i,j,&w);
}
G.kind = DN;
return OK;
}
int CreateUDN(ALGraph &G)//构造无向网
{
cout<<"输入顶点数,边数:"<<endl;
cin>>G.vexnum>>G.arcnum;
int i,j,k,w;
for(i=0; i<G.vexnum; i++)//构造顶点向量
{
cout<<"输入第"<<i+1<<"个顶点的名称:";
G.vertices[i].data = (VertexType)malloc( sizeof(char) );
cin>>G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
char *v1, *v2;
v1 = (char*)malloc(sizeof(char));
v2 = (char*)malloc(sizeof(char));
for(k=0; k<G.arcnum; k++)
{
cout<<"输入相连的边及权值(v1,v2,w):";
cin>>v1>>v2>>w;
i = LocateVex(G,v1);//边的起点
j = LocateVex(G,v2);//边的终点
CreateSub(G,i,j,&w);
CreateSub(G,j,i,&w);
}
G.kind = UDN;
return OK;
}
VertexType GetVex(ALGraph G, int v)//返回图中第V个顶点
{
if(v<0 || v>G.vexnum)
return NULL;
return G.vertices[v-1].data;
}
int PutVex(ALGraph &G, VertexType v, VertexType value)//修改图中顶点v的名称为value
{
int i;
i = LocateVex(G,v);
if(i<0)
return ERROR;
else
strcpy(G.vertices[i].data,value);
return OK;
}
ArcNode* FirstAdjVex(ALGraph G, VertexType v)//返回顶点V的第一个邻接点
{
int i;
i = LocateVex(G,v);
if(i<0)
return NULL;
else
return G.vertices[i].firstarc;
}
ArcNode* NextAdjVex(ALGraph G, VertexType v, VertexType w)//返回顶点V的(相对于w)下一个邻接点
{
int i,j,k;
i = LocateVex(G,v);
j = LocateVex(G,w);
if(i<0 || j<0)
return NULL;
ArcNode *p;
p = G.vertices[i].firstarc;
while(p)
{
if(p->adjvex == j)
return p->nextarc;
p = p->nextarc;
}
}
void InsertVex(ALGraph &G, VertexType v)//插入顶点
{
G.vertices[G.vexnum].data = (VertexType)malloc( sizeof(char) );
strcpy(G.vertices[G.vexnum].data,v);
G.vertices[G.vexnum].firstarc = NULL;
G.vexnum++;
}
int DeleteVex(ALGraph &G, VertexType v)//删除顶点
{
int i,k,j;
k = LocateVex(G,v);
if(G.kind < 2)//有向
j = 1;
else //无向
j = 0;
if(v<0)
return ERROR;
ArcNode *p,*q;
p = G.vertices[k].firstarc;//p指向顶点v的链表
while(p) //删除顶点v的链表
{
q = p;
G.vertices[k].firstarc = p->nextarc;
p = p->nextarc;
free(q);
G.arcnum--; //边数减1
}
for(i=0; i<G.vexnum; i++)//对邻接表其余顶点链表操作,删除有顶点v的指针
{
p = G.vertices[i].firstarc;
if(p)
{
if(p->adjvex == k) //删除第一个结点(顶点v是第一个结点)
{
G.vertices[i].firstarc = p->nextarc;
free(p);
G.arcnum = G.arcnum - j;
}
else //删除第一个后的结点(顶点v不是第一个结点)
{
q = p;
p = p->nextarc;
while(p)
{
if(p->adjvex == k)
{
q->nextarc = p->nextarc;
free(p);
G.arcnum = G.arcnum - j;//有向:边再减1;无向:不用再减1
break;
}
q = p;
p = p->nextarc;
}
}
}
}
for(i=k; i<G.vexnum-1; i++)//邻接表第k个位置后都往前移
G.vertices[i] = G.vertices[i+1];
G.vexnum--; //顶点数减1
for(i=0; i<G.vexnum; i++) //由于邻接表位置的挪动,导致各顶点链表中的adjvex域都错位,应重新调整
{
p = G.vertices[i].firstarc;
while(p)
{
if(p->adjvex > k) //第k个位置后的链表都往前移了,因此p->adjvex > k的情况下,都减1
p->adjvex = p->adjvex -1;
p = p->nextarc;
}
}
}
int InsertArc(ALGraph &G, VertexType v, VertexType w)//插入一条边或弧
{
int i,j,weight;
i = LocateVex(G,v);//尾
j = LocateVex(G,w);//头
if(i<0 || j<0)
return ERROR;
G.arcnum++;
if(G.kind % 2 == 1)//网
{
cout<<"输入权值:";
cin>>weight;
}
else //图
weight = 1;
if(G.kind < 2)//有向
CreateSub(G,i,j,&weight);
else //无向
{
CreateSub(G,i,j,&weight);
CreateSub(G,j,i,&weight);
}
return OK;
}
void DeleteSub(ALGraph &G, int i, int j)//删除边或弧的辅助函数
{
ArcNode *p, *pre;
p = G.vertices[i].firstarc;
if(p->adjvex == j)
{
G.vertices[i].firstarc = p->nextarc;
free(p);
}
else
{
pre = p;
p = p->nextarc;
while(p)
{
if(p->adjvex == j)
{
pre->nextarc = p->nextarc;
free(p);
break;
}
pre = p;
p = p->nextarc;
}
}
}
int DeleteArc(ALGraph &G, VertexType v, VertexType w)//删除一条边
{
int i,j,k;
i = LocateVex(G,v);//尾
j = LocateVex(G,w);//头
if(i<0 || j<0)
return ERROR;
if(G.kind < 2)//有向
DeleteSub(G,i,j);
else //无向
{
DeleteSub(G,i,j);
DeleteSub(G,j,i);
}
G.arcnum--;
return OK;
}
void Display(ALGraph G)
{
int i;
ArcNode *t;
cout<<"边数:"<<G.arcnum<<endl;
cout<<"顶点数:"<<G.vexnum<<endl;
for(i=0; i<G.vexnum; i++)
{
cout<<i+1<<": "<<G.vertices[i].data;
t = G.vertices[i].firstarc;
while(t)
{
cout<<G.vertices[t->adjvex].data;
t = t->nextarc;
}
cout<<endl;
}
}
void Visit(VertexType e)
{
cout<<e;
}
void DFS(ALGraph G, int i)
{
visited[i] = TRUE;
Visit(G.vertices[i].data);
ArcNode *w;
for(w=FirstAdjVex(G,G.vertices[i].data); w!=NULL; w=NextAdjVex(G,G.vertices[i].data,G.vertices[w->adjvex].data))
{
if(!visited[w->adjvex])
DFS(G,w->adjvex);
}
}
void DFSTraverse(ALGraph G, void(*Visit)(VertexType))//深度优先遍历
{
int i;
for(i=0; i<G.vexnum; i++)
visited[i] = FALSE;
for(i=0; i<G.vexnum; i++)
{
if(!visited[i])
DFS(G,i);
}
cout<<endl;
}
void BFSTraverse(ALGraph G, void(*Visit)(VertexType))//广度优先搜索算法
{
int i,u;
ArcNode *w;
for(i=0; i<G.vexnum; i++)
visited[i] = FALSE;
queue<int> Q;
for(i=0; i<G.vexnum; i++)
{
if(!visited[i])
{
visited[i] = TRUE;
Visit(G.vertices[i].data);
Q.push(i);
while(!Q.empty())
{
u = Q.front();
Q.pop();
for(w=FirstAdjVex(G,G.vertices[u].data); w!=NULL; w=NextAdjVex(G,G.vertices[u].data,G.vertices[w->adjvex].data))
{
if(!visited[w->adjvex])
{
visited[w->adjvex] = TRUE;
Visit(G.vertices[w->adjvex].data);
Q.push(w->adjvex);
}
}
}
}
}
cout<<endl;
}
int main(int argc, char* argv[])
{
ALGraph G;
CreateGraph(G);
Display(G);
DFSTraverse(G,Visit);
BFSTraverse(G,Visit);
return 0;
}
数据结构---图(邻接表)
最新推荐文章于 2024-07-17 20:24:19 发布