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;
}
Beispiel #3
0
//广度优先遍历无向图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");	
}
Beispiel #4
0
//深度优先遍历无向图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");
}
Beispiel #5
0
//构造图(只针对有向)
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;
		*/
	}
}
Beispiel #7
0
//深度优先遍历无向图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);
		}
	}
	*/
}
Beispiel #8
0
// 采用邻接表存储结构,构造没有相关信息的图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;
}