数据结构---图的连通性
来源:互联网 发布:绝对领域 知乎 编辑:程序博客网 时间:2024/03/29 00:15
//头文件//以数组形式构造图#pragma once#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;}// Graph_Connectivity.cpp : Defines the entry point for the console application./*-----CODE FOR FUN----------------------CREATED BY Dream_Whui-------------2015-2-11--------------------*///求无向图G的深度优先生成森林,孩子兄弟链表T#include "stdafx.h"#include "Graph.h" //引入图的头文件typedef char* Elemtype;typedef struct CSNode//树的存储结构:孩子兄弟链表结构{ Elemtype data; struct CSNode *firstchild, *nextsibling;}CSNode, *CSTree;void DFSTree(MGraph G, int i, CSTree &T)//从第i个顶点出发深度优先遍历图G,建立以T为根的生成树{ int first; VertexType w; CSTree p,q; visited[i] = TRUE; first = TRUE; for(w=FirstAdjVex(G,G.vexs[i]); w!=NULL; w=NextAdjVex(G,G.vexs[i],w)) { if(!visited[LocateVex(G,w)]) { p = (CSTree)malloc(sizeof(CSNode));//分配孩子结点,并赋值 p->data = (Elemtype)malloc(sizeof(char)); p->data = w; p->firstchild = NULL; p->nextsibling = NULL; if(first) //w是v的第一个未被访问的邻接顶点 { T->firstchild = p; first = FALSE; } else q->nextsibling = p; //是上一个邻接顶点的右兄弟结点 q = p; DFSTree(G,LocateVex(G,w),q); //从第w个顶点出发深度优先遍历图G,建立子生成树q } }}void DFSForest(MGraph G, CSTree &T)//无向图G的深度优先生成森林,孩子兄弟链表T{ T = NULL; CSTree p,q; int i; for(i=0; i<G.vexnum; i++) visited[i] = FALSE; for(i=0; i<G.vexnum; i++) { if(!visited[i]) //第i个结点为新的生成树的根结点 { p = (CSTree)malloc(sizeof(CSNode));//分配根结点,并赋值 p->data = (Elemtype)malloc(sizeof(char)); p->data = GetVex(G,i+1);//返回第i+1个顶点的名字(i以0起,即结点以i+1起) p->firstchild = NULL; p->nextsibling = NULL; if(!T) T = p; //第一颗生成树的根 else q->nextsibling = p;//是其他生成树的根(前一颗的根的“兄弟”) q = p; //q指示当前生成树的根 DFSTree(G,i,p); } }}void DFS_Traverse(CSTree T) //深度优先输出各顶点的名字{ if(T) { cout<<T->data; DFS_Traverse(T->firstchild); DFS_Traverse(T->nextsibling); }}int main(int argc, char* argv[]){ MGraph G; CSTree T; CreateGraph(G); DFSForest(G,T); DFS_Traverse(T); return 0;}
0 0
- 数据结构---图的连通性
- 数据结构 图 图的连通性
- 11.23数据结构----图的遍历/连通性
- 数据结构的连通性问题
- 数据结构---->图的连通性和最小生成树
- 49. 数据结构笔记之四十九图的连通性问题
- 图的连通性小结
- 图的连通性
- 判断图的连通性
- 【图的连通性】poj2117Electricity
- 图的连通性判断
- 判断图的连通性
- 判断图的连通性
- 图的连通性问题
- 图的连通性问题
- 图的连通性问题
- 图的连通性问题
- 图的连通性判断
- Mybatis调用存储过程出现NullPointerException错误
- 数据结构---图(数组表示法)
- A*算法源码
- 使用hadoop存储图片服务器
- Kernel中GPIO的Sysfs接口的使用
- 数据结构---图的连通性
- Android反调试之 AntiEmulator 检测安卓模拟器
- cuda的优化技术
- POJ 2823 Sliding Window(单调队列)
- NYOJ--21(搜索)-题目-----------------------------三个水杯
- 数据结构--最小生成树(Prim算法)
- 我的maven项目常用配置
- 【学习心得】linux下多客户端批量操作脚本(含expect交互)
- 数据结构---图(邻接表)