数据结构---图(数组表示法)
来源:互联网 发布:mac mini好吗 编辑:程序博客网 时间:2024/04/26 06:35
// MGraph_array.cpp : Defines the entry point for the console application./*-----CODE FOR FUN----------------------CREATED BY Dream_Whui-------------2015-2-9--------------------*/#include "stdafx.h"#include <iostream>#include <queue>using namespace std;#define INFINITY INT_MAX#define NAX_VERTEX_NUM 20#define VRtype int//#define InfoType char*#define VertexType char*#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2#define INFEASIBLE -1bool visited[NAX_VERTEX_NUM];void(*VisitFunc)(VertexType);typedef enum{ DG,DN,UDG,UDN//有向图,有向网,无向图,无向网}GraphKind;typedef struct ArcCell{ VRtype adj;//无权图,用0或1;带权图,即权值 //InfoType *info; }ArcCell, AdjMatrix[NAX_VERTEX_NUM][NAX_VERTEX_NUM];typedef struct //定义图的结构{ VertexType vexs[NAX_VERTEX_NUM];//顶点向量 AdjMatrix arcs; //邻接矩阵 int vexnum,arcnum; //定点数,边(弧)数 GraphKind kind; //图的种类标记}MGraph;int CreateDG(MGraph &G);//构造有向图int CreateDN(MGraph &G);//构造有向网int CreateUDG(MGraph &G);//构造无向图int CreateUDN(MGraph &G);//构造无向网int CreateGraph(MGraph &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(MGraph G, VertexType V)//顶点V在图中的位置{ int i; for(i=0; i<G.vexnum; i++) { if(strcmp(G.vexs[i],V) == 0) return i; } return -1;//不存在,返回-1}int CreateUDG(MGraph &G)//构造无向图{ cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = 0; //G.arcs[i][j].info = 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);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = 1;//权值 G.arcs[j][i] = G.arcs[i][j];//无向图中,邻接矩阵对称 } G.kind = UDG;//无向图 return OK;}int CreateDG(MGraph &G)//构造有向图{ cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = 0; //G.arcs[i][j].info = 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);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = 1;//权值 } G.kind = DG;//有向图 return OK;}int CreateUDN(MGraph &G)//采用数组(邻接矩阵)表示法,构造无向网{ //int IncInfo; cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = INFINITY; //G.arcs[i][j].info = NULL; } } char *v1, *v2; v1 = (char*)malloc(sizeof(char)); v2 = (char*)malloc(sizeof(char)); int w; for(k=0; k<G.arcnum; k++)//构造邻接矩阵 { cout<<"输入边及其权重(v1,v2,w):"; cin>>v1>>v2>>w; i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = w;//权值 G.arcs[j][i] = G.arcs[i][j];//无向网中,邻接矩阵对称 } G.kind = UDN;//无向网 return OK;}int CreateDN(MGraph &G)//采用数组(邻接矩阵)表示法,构造有向网{ //int IncInfo; cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = INFINITY; //G.arcs[i][j].info = NULL; } } char *v1, *v2; v1 = (char*)malloc(sizeof(char)); v2 = (char*)malloc(sizeof(char)); int w; for(k=0; k<G.arcnum; k++)//构造邻接矩阵 { cout<<"输入边及其权重(v1,v2,w):"; cin>>v1>>v2>>w; i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = w;//权值 } G.kind = DN;//有向网 return OK;}VertexType GetVex(MGraph G, int v)//返回图中第V个顶点{ if(v<1 || v>G.vexnum) return NULL; else return G.vexs[v-1];//顶点数组以标号0开始}int PutVex(MGraph &G, VertexType v, VertexType value)//修改图中顶点v的名称为value{ int i = LocateVex(G,v); if(i<0) return ERROR; else strcpy(G.vexs[i],value); return OK;}VertexType FirstAdjVex(MGraph G, VertexType v)//返回顶点V的第一个邻接点{ int i,j,k; k = LocateVex(G,v);//定位顶点v在图中的位置 if(k<0) return NULL; if(G.kind % 2 == 1)//网 j = INFINITY; else j = 0;//图 for(i=0; i<G.vexnum; i++) { if(G.arcs[k][i].adj != j)//邻接矩阵中该行第一个不为j的分量所在的列号 return GetVex(G,i+1); } return NULL;}VertexType NextAdjVex(MGraph G, VertexType v, VertexType w)//返回顶点V的(相对于w)下一个邻接点{ int i,j,k,p; i = LocateVex(G,v); j = LocateVex(G,w); if(i<0 || j<0) return NULL; if(G.kind % 2 == 1)//网 k = INFINITY; else k = 0;//图 for(p=j+1; p<G.vexnum; p++) { if(G.arcs[i][p].adj != k) return GetVex(G,p+1); } return NULL;}void InsertVex(MGraph &G, VertexType v)//插入顶点{ int j,i; if(G.kind % 2 == 1) j = INFINITY;//网 else j = 0;//图 G.vexs[G.vexnum] = (VertexType)malloc(sizeof(VertexType)); strcpy(G.vexs[G.vexnum],v); for(i=0; i<=G.vexnum; i++) G.arcs[G.vexnum][i].adj = G.arcs[i][G.vexnum].adj = j;//初始化权值 G.vexnum++;}int DeleteVex(MGraph &G, VertexType v)//删除顶点{ int i,j,k,p; k = LocateVex(G,v); if(k<0) return ERROR; if(G.kind % 2 == 1) j = INFINITY;//网 else j = 0;//图 for(i=0; i<G.vexnum; i++)//入弧(出度) if(G.arcs[k][i].adj != j) G.arcnum--; if(G.kind < 2)//有向 for(i=0; i<G.vexnum; i++) if(G.arcs[i][k].adj != j) G.arcnum--; for(i=k+1; i<G.vexnum; i++)//顶点向量第k个之后的都往前移 strcpy(G.vexs[i-1],G.vexs[i]); //free(G.vexs[i-1]); G.vexs[i-1] = NULL; for(i=0; i<G.vexnum; i++)//邻接矩阵中每行从第k列之后的都往前移 { for(p=k+1; p<G.vexnum; p++) G.arcs[i][p-1] = G.arcs[i][p]; G.arcs[i][p-1].adj = j; } G.arcs[i-1][p-1].adj = j; for(i=k+1; i<G.vexnum; i++)//邻接矩阵中每列从第k行之后的都往上移 { for(p=0; p<G.vexnum-1; p++) { G.arcs[i-1][p] = G.arcs[i][p]; if(i == G.vexnum-1) G.arcs[i][p].adj = j; } } G.vexnum--; return OK;}int InsertArc(MGraph &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)//有向 G.arcs[i][j].adj = weight; else//无向 G.arcs[j][i].adj= G.arcs[i][j].adj=weight; return OK;}int DeleteArc(MGraph &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)//网 weight = INFINITY; else//图 weight = 1; if(G.kind < 2)//有向 G.arcs[i][j].adj = weight; else G.arcs[i][j].adj = G.arcs[j][i].adj = weight; return OK;}void Display(MGraph G)//输出邻接矩阵{ int i,j; for(i=0; i<G.vexnum; i++) { for(j=0; j<G.vexnum; j++) { cout<<"("<<G.vexs[i]<<"->"<<G.vexs[j]<<","; if(G.arcs[i][j].adj == INFINITY) cout<<"oo"; else cout<<G.arcs[i][j].adj; cout<<")"<<" "; } cout<<endl; }}void Visit(VertexType e){ cout<<e;}void DFS(MGraph G, int v){ visited[v] = TRUE;//访问第v个结点 VisitFunc(G.vexs[v]); VertexType w; for(w=FirstAdjVex(G,G.vexs[v]); w!=NULL; w=NextAdjVex(G,G.vexs[v],w) )//对第v个顶点尚未访问的邻接结点w递归调用DFS { if(!visited[LocateVex(G,w)]) DFS(G,LocateVex(G,w)); }}void DFSTraverse(MGraph G, void(*Visit)(VertexType))//深度优先遍历{ int v; VisitFunc = Visit; for(v=0; v<G.vexnum; v++) visited[v] = FALSE;//访问标志数组 for(v=0; v<G.vexnum; v++) if(!visited[v])//对尚未访问的顶点调用DFS DFS(G,v); cout<<endl;}void BFSTraverse(MGraph G, void(*Visit)(VertexType))//广度优先搜索算法{ int i,u; VertexType 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.vexs[i]); Q.push(i); while(!Q.empty()) { u = Q.front();//对头元素出队并置为u Q.pop(); for(w=FirstAdjVex(G,G.vexs[u]); w!=NULL; w=NextAdjVex(G,G.vexs[u],w)) { //w为u的尚未访问的邻接顶点 if(!visited[LocateVex(G,w)]) { visited[LocateVex(G,w)] = TRUE; Visit(w); Q.push(LocateVex(G,w)); } } } } } cout<<endl;}int main(int argc, char* argv[]){ MGraph G; CreateGraph(G); int i,j; Display(G); for(i=0; i<G.vexnum; i++) cout<<"第"<<i+1<<"个顶点的名字:"<<GetVex(G,i+1)<<endl; cout<<endl; VertexType w; for(i=1; i<=G.vexnum; i++) { for(w=FirstAdjVex(G,G.vexs[i-1]); w!=NULL; w=NextAdjVex(G,G.vexs[i-1],w)) cout<<w<<" "; cout<<endl; } DFSTraverse(G,Visit); BFSTraverse(G,Visit); //PutVex(G,"v1","v0"); //for(i=0; i<G.vexnum; i++) //cout<<"第"<<i+1<<"顶点的名字:"<<GetVex(G,i+1)<<endl; //cout<<endl; //cout<<FirstAdjVex(G,G.vexs[0])<<endl; //cout<<NextAdjVex(G,G.vexs[0],G.vexs[1])<<endl; //DeleteVex(G,G.vexs[0]); //Display(G); //InsertVex(G,"A1"); //Display(G); return 0;}
0 0
- 数据结构---图(数组表示法)
- 数据结构学习笔记 --- 图(数组表示法)
- 数据结构学习笔记 --- 图(数组表示法)
- 数据结构之图的数组表示法
- 图的数组表示法-数据结构(18)
- C数据结构学习历程(5) 图之数组表示法
- 数据结构——图的数组实现(邻接矩阵表示法)
- 图 数组表示法
- 图--邻接矩阵(数组表示法)
- C数据结构学习历程(5) 图之数组表示法的BFS
- 【数据结构】算法7.1-7.2 图的存储结构-数组表示法
- 图解数据结构(1)——大圈表示法、动态数组和单向链表
- 图解数据结构(1)——大圈表示法、动态数组和单向链表
- 图解数据结构(1)——大圈表示法、动态数组和单向链表
- 图解数据结构(1)——大圈表示法、动态数组和单向链表
- 图解数据结构(1)——大圈表示法、动态数组和单向链表
- 图解数据结构(1)——大圈表示法、动态数组和单向链表
- 数据结构之---C语言实现图的数组(邻接矩阵)存储表示
- 数据结构--哈弗曼树
- apache 配置
- Ibatis结合MySQL数据库的使用方法
- C++模板类
- Mybatis调用存储过程出现NullPointerException错误
- 数据结构---图(数组表示法)
- A*算法源码
- 使用hadoop存储图片服务器
- Kernel中GPIO的Sysfs接口的使用
- 数据结构---图的连通性
- Android反调试之 AntiEmulator 检测安卓模拟器
- cuda的优化技术
- POJ 2823 Sliding Window(单调队列)
- NYOJ--21(搜索)-题目-----------------------------三个水杯