void MGraphAL::initAdjacencyOne(std::string record) { if (record == "") return; //这个是一条弧的记录 std::string name1 = record.substr(0, 2); //如:v1 std::string name2 = record.substr(3, 2); int i = locateVex(name1); int j = locateVex(name2); ArcNode *p = new ArcNode(); p->adjvex = j; //这个弧指向的对象的数组的下标位置 p->nextarc = vertices[i].firstarc; //头插法,加入到这个链表的头中 vertices[i].firstarc = p; }
void MGraphAL::initAdjacencyOneWithWeight(std::string record) { if (record == "") return; //一条记录 v1:v2:7 std::string name1 = record.substr(0, 2); std::string name2 = record.substr(3, 2); int weight = atoi(record.substr(6, 1).c_str()); int i = locateVex(name1); int j = locateVex(name2); ArcNode *p = new ArcNode(); p->adjvex = j; //这个弧指向的下一个节点 p->weight = weight; //权值 p->nextarc = vertices[i].firstarc; //把这个节点加入到这个链表的头 vertices[i].firstarc = p; }
//广度优先遍历无向图G(相当于树的按层次遍历)(非递归算法) void BFSTraverseGraph(ALGraph G){ int queue[MAX_VERTEX_NUM];//维护一个队列来存储访问图的顶点的(位置)信息 int front = 0, rail = 0;//初始化队头、队尾指针,为空队列 //初始化访问标志数组 for(int i = 0; i < G.vexnum; i++){ visited[i] = 0;//0表示未被访问,1表示已被访问 } printf("请输入遍历的起始顶点(如:v1):"); VertexType startVex; scanf("v%d", &startVex); int startVexPos = locateVex(G, startVex); printf("一条广度优先遍历序列为:"); queue[rail++] = startVexPos;//起点先入队 int ivex;// = startVexPos; ArcNode *p; while(front != rail){//不是空队列 ivex = queue[front++];//队头元素出队 if(!visited[ivex]){ visited[ivex] = 1; printf("v%d ", G.vexs[ivex].data); } p = G.vexs[ivex].firstarc; while(p){//p指向与ivex的邻接的(同一个层次的)还未被顶点 if(!visited[p->adjvex]) queue[rail++] = p->adjvex;//入队 p = p->nextarc; } } printf("\n"); }
//深度优先遍历无向图G(相当于树的先序遍历)(非递归算法) void DFSTraverseGraph2(ALGraph G){ int stack[MAX_VERTEX_NUM];//维护一个栈来存储访问图的顶点的(位置)信息 int top = 0;//初始化栈顶指针,为空栈 //初始化访问标志数组 for(int i = 0; i < G.vexnum; i++){ visited[i] = 0;//0表示未被访问,1表示已被访问 } printf("请输入遍历的起始顶点(如:v1):"); VertexType startVex; scanf("v%d", &startVex); int startVexPos = locateVex(G, startVex); printf("一条深度优先遍历序列为:"); ArcNode *p;// = G.vexs[startVexPos].firstarc; int ivex = startVexPos; while(!visited[ivex] || top!=-1){//栈不为空 if(!visited[ivex]){//第vex结点没有被访问过 visited[ivex] = 1; printf("v%d ", G.vexs[ivex].data); stack[top++] = ivex; } p = G.vexs[ivex].firstarc; while(p && visited[p->adjvex])//p不为空且p已经被访问过,就跳过 p = p->nextarc; //此时p指向以当前顶点为头的且未被访问第一个尾顶点 if(p){//如果p不为空 ivex = p->adjvex; }else{//如果p为空,说明当前顶点的所有和他有路径相通的顶点均已访问,则栈顶元素出栈,查找下一个尚未被访问的顶点 ivex = stack[--top];//栈顶元素出栈 } } printf("\n"); }
//构造图(只针对有向) void createGraph(AMLGraph &G) { int i,j,k; int IncInfo; EBox *p; VertexType v1,v2; printf("请输入有向图的顶点数,弧数,是否为带权图(是:1,否:0): \n"); cin>>IncInfo; IncInfo = IncInfo?1:0; char filename[24]; sprintf(filename,"GData6_%d.txt",IncInfo); ifstream fin(filename,ios_base::in); if(fin.is_open()) { fin>>G.vexnum>>G.edgenum; for(i=0;i<G.vexnum;++i) { fin>>G.adjmulist[i].data; G.adjmulist[i].firstedg=NULL; } for(k=0;k<G.edgenum;++k) { fin>>v1>>v2; i=locateVex(G,v1); j=locateVex(G,v2); p=(EBox *)malloc(sizeof(EBox)); p->mark=unvisited; p->ivex=i; p->ilink=G.adjmulist[i].firstedg; G.adjmulist[i].firstedg=p; p->jvex=j; p->jlink=G.adjmulist[j].firstedg; G.adjmulist[j].firstedg=p; if(IncInfo) { p->info=(InfoType*)malloc(sizeof(InfoType)); fin>>(*p->info); } else p->info=NULL; }
//采用邻接表表示法构造有向图G void createDG(ALGraph &G){ printf("输入顶点数和弧数如:(5,3):"); scanf("%d,%d", &G.vexnum, &G.arcnum); //构造顶点向量,并初始化 printf("输入%d个顶点(以空格隔开如:v1 v2 v3):", G.vexnum); getchar();//吃掉换行符 for(int m = 0; m < G.vexnum; m++){ scanf("v%d", &G.vexs[m].data); G.vexs[m].firstarc = NULL;//初始化为空指针////////////////重要!!! getchar();//吃掉空格符 } //构造邻接表 VertexType v1, v2;//分别是一条弧的弧尾和弧头(起点和终点) //VRType w;//对于无权图或网,用0或1表示相邻否;对于带权图或网,则为相应权值 printf("\n每行输入一条弧依附的顶点(先弧尾后弧头)如:v1v2:\n"); fflush(stdin);//清除残余后,后面再读入时不会出错 int i = 0, j = 0; for(int k = 0; k < G.arcnum; k++){ scanf("v%dv%d",&v1, &v2); fflush(stdin);//清除残余后,后面再读入时不会出错 i = locateVex(G, v1);//弧起点 j = locateVex(G, v2);//弧终点 //采用“头插法”在各个顶点的弧链头部插入弧结点 ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));//构造一个弧结点,作为弧vivj的弧头(终点) p1->adjvex = j; //p1->w = w; p1->nextarc = G.vexs[i].firstarc; G.vexs[i].firstarc = p1; /*因为是有向图,所以不必创建2个弧结点 ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));//构造一个弧结点,作为弧vivj的弧尾(起点) p2->adjvex = i; //p2->w = w; p2->nextarc = G.vexs[j].firstarc; G.vexs[j].firstarc = p2; */ } }
//深度优先遍历无向图G(相当于树的先序遍历)(递归算法) void DFSTraverseGraph(ALGraph G){ //初始化访问标志数组 for(int i = 0; i < G.vexnum; i++){ visited[i] = 0;//0表示未被访问,1表示已被访问 } printf("请输入遍历的起始顶点(如:v1):"); VertexType startVex; scanf("v%d", &startVex); int startVexPos = locateVex(G, startVex); printf("一条深度优先遍历序列为:"); if(!visited[startVexPos]) DFS(G, startVexPos); printf("\n"); /* for(i = 0; i < G.vexnum; i++){//图中每个顶点至多调用一次DFS函数 if(!visited[i]){//对还未访问过的顶点调用DFS DFS(G, i); } } */ }
// 采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图) int createGraph(ALGraph *G){ int i,j,k; int w;//权值 VertexType va,vb; char *tmp_vexs[9] = {"V1","V2","V3","V4","V5","V6","V7","V8","V9"};//写死的顶点数组 char *tmp_arcs[11][2] = {{"V1","V2"},{"V1","V3"},{"V1","V4"},{"V2","V5"},{"V3","V5"},{"V4","V6"},{"V5","V7"},{"V5","V8"},{"V6","V8"},{"V7","V9"},{"V8","V9"}};//写死的边数组 int tmp_w[11] = {6,4,5,1,1,2,8,7,4,2,4}; ArcNode *p; // 请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3) printf("Please enter graph type(directed graph:0,directed network,AG,AN):\n"); // scanf("%d",&G->kind); G->kind = 1; printf("%d",G->kind); // 请输入图的顶点数和边数:(空格) printf("\nPlease enter graph vertex amount and side:(space)\n"); // scanf("%d%d",&G->vexnum,&G->arcnum); G->vexnum = 9;G->arcnum = 11;//写死的,方便调试 printf("%d,%d\n",G->vexnum,G->arcnum); // 请输入%d个顶点的值(<%d个字符) printf("Please enter %d vertex value(smaller than %d char):\n",G->vexnum,MAX_NAME); // 构造顶点向量 for(i=0;i<G->vexnum;i++){ // scanf("%s",G->vertices[i].data); strcpy(G->vertices[i].data,tmp_vexs[i]); printf("%s ",G->vertices[i].data); G->vertices[i].firstarc = NULL; } // 网 if(G->kind==1||G->kind==3){ // 请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔) printf("\nPlease enter arc(side) weight,arc tail and arc head(split by space):\n"); }else{// 图 // 请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔) printf("\nPlease enter arc(side) arc tail and arc head(split by space):\n"); } // 构造表结点链表 for(k=0;k<G->arcnum;k++){ // 网 if(G->kind==1||G->kind==3){ // scanf("%d%s%s",&w,va,vb); strcpy(va,tmp_arcs[k][0]);//弧尾 strcpy(vb,tmp_arcs[k][1]);//弧头 w = tmp_w[k];//权值 printf("tail='%s',head='%s',w=%d\n",va,vb,w); }else{//图 // scanf("%s%s",va,vb); } i = locateVex(*G,va);//弧尾 j = locateVex(*G,vb);//弧头 p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = j; // 网 if(G->kind==1||G->kind==3){ p->info = (int*)malloc(sizeof(int)); *(p->info) = w; }else{ p->info = NULL;//图 } p->nextarc = G->vertices[i].firstarc;//插在表头 G->vertices[i].firstarc = p; if(G->kind>=2){//无向图或网,产生第二个表结点 p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = i; // 无向网 if(G->kind==3){ p->info = (int*)malloc(sizeof(int)); *(p->info) = w; }else{ p->info = NULL;//无向图 } p->nextarc = G->vertices[j].firstarc;//插在表头 G->vertices[j].firstarc = p; } } return 1; }