数据结构---图(邻接表)
来源:互联网 发布:绝对领域 知乎 编辑:程序博客网 时间:2024/04/26 03:36
// 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 -1typedef 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;}
1 0
- 数据结构---图(邻接表)
- 数据结构---图---邻接表
- 数据结构学习笔记 --- 图(邻接表)
- 数据结构学习笔记 --- 图(邻接表)
- 数据结构---图的邻接表
- 数据结构(C++)——图(邻接表)
- 数据结构之用邻接表实现图(详解)
- 数据结构学习笔记 图:邻接表(严蔚敏版)
- 【数据结构】图的构建(邻接表法)
- 数据结构:图(邻接表存储 c++实现)
- 数据结构:图(邻接多重表存储 c++实现)
- java数据结构之图(邻接矩阵和邻接表)
- 数据结构练习题 017 图 邻接多重表
- 【数据结构】图邻接表存储实现
- 数据结构:图的实现--邻接表
- 数据结构:图的实现--邻接表
- 数据结构之图的邻接多重表
- 数据结构:图的实现--邻接表
- POJ 2823 Sliding Window(单调队列)
- NYOJ--21(搜索)-题目-----------------------------三个水杯
- 数据结构--最小生成树(Prim算法)
- 我的maven项目常用配置
- 【学习心得】linux下多客户端批量操作脚本(含expect交互)
- 数据结构---图(邻接表)
- 显示缓存内容
- enum和int的相互转换
- 数据结构---图(求关节点)
- matlab新手入门篇
- SRTM DEM 下载网址
- 另类case when
- 剪格子
- Math类常用的常量和方法