1. 程式人生 > >_DataStructure_C_Impl:求圖G中從頂點u到頂點v的一條簡單路徑

_DataStructure_C_Impl:求圖G中從頂點u到頂點v的一條簡單路徑

下一個 all clear 第一個 sta 找到 tac 輸出 content

#pragma once
#include<stdio.h>
#include<stdlib.h>
#define StackSize 100
typedef int DataType;	//棧元素類型定義
typedef struct{
	DataType stack[StackSize];
	int top;
}SeqStack;
//將棧初始化為空棧僅僅須要把棧頂指針top置為
void InitStack(SeqStack *S){
	S->top=0;//把棧頂指針置為0
}
//推斷棧是否為空。棧為空返回1,否則返回0
int StackEmpty(SeqStack S){
	if(S.top==0)
		return 1;
	else
		return 0;
}
//取棧頂元素。將棧頂元素值返回給e。並返回1表示成功;否則返回0表示失敗。
int GetTop(SeqStack S,DataType *e){
	if(S.top<=0){		//在取棧頂元素之前。推斷棧是否為空
		printf("棧已經空!\n");
		return 0;
	}else{
		*e=S.stack[S.top-1];	//在取棧頂元素
		return 1;
	}
}
//將元素e進棧,元素進棧成功返回1,否則返回0
int PushStack(SeqStack *S,DataType e){
	if(S->top>=StackSize){	//在元素進棧前。推斷是否棧已經滿
		printf("棧已滿,不能進棧!

\n"); return 0; }else{ S->stack[S->top]=e; //元素e進棧 S->top++; //改動棧頂指針 return 1; } } //出棧操作。將棧頂元素出棧,並將其賦值給e。

出棧成功返回1。否則返回0 int PopStack(SeqStack *S,DataType *e){ if(S->top<=0){ //元素出棧之前。推斷棧是否為空 printf("棧已經沒有元素。不能出棧!\n"); return 0; }else{ S->top--; //先改動棧頂指針。即出棧 *e=S->stack[S->top]; //將出棧元素賦值給e return 1; } } //求棧的長度。即棧中元素個數,棧頂指針的值就等於棧中元素的個數 int StackLength(SeqStack S){ return S.top; } //清空棧的操作 void ClearStack(SeqStack *S){ S->top=0; }

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"SeqStack.h"
typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;
#define MaxSize 50	//最大頂點個數
typedef enum{DG,DN,UG,UN}GraphKind;	//圖的類型:有向圖、有向網、無向圖和無向網
//邊結點的類型定義
typedef struct ArcNode{
	int adjvex;		//弧指向的頂點的位置
	InfoPtr *info;	//弧的權值
	struct ArcNode *nextarc;	//指示下一個與該頂點相鄰接的頂點
}ArcNode;
//頭結點的類型定義
typedef struct VNode{
	VertexType data;	//用於存儲頂點
	ArcNode *firstarc;	//指示第一個與該頂點鄰接的頂點
}VNode,AdjList[MaxSize];
//圖的類型定義
typedef struct{
	AdjList vertex;	 //頭結點
	int vexnum,arcnum;	//圖的頂點數目與弧的數目
	GraphKind kind;	//圖的類型
}AdjGraph;
//求圖G中從頂點u到頂點v的一條簡單路徑
void BriefPath(AdjGraph G,int u,int v){
	int k,i;
	SeqStack S;
	ArcNode *p;
	int visited[MaxSize];
	int parent[MaxSize];	//存儲已經訪問頂點的前驅頂點
	InitStack(&S);
	for(k=0;k<G.vexnum;k++)
		visited[k]=0;	//訪問標誌初始化
	PushStack(&S,u);	//開始頂點入棧
	visited[u]=1;		//訪問標誌置為1
	while(!StackEmpty(S)){	//廣度優先遍歷圖,訪問路徑用parent存儲
		PopStack(&S,&k);
		p=G.vertex[k].firstarc;
		while(p!=NULL){
			if(p->adjvex==v){	//假設找到頂點v
				parent[p->adjvex]=k;		//頂點v的前驅頂點序號是k
				printf("頂點%s到頂點%s的路徑是:",G.vertex[u].data,G.vertex[v].data);
				i=v;
				do{			//從頂點v開始將路徑中的頂點依次入棧
					PushStack(&S,i);
					i=parent[i];
				}while(i!=u);
				PushStack(&S,u);
				while(!StackEmpty(S)){ //從頂點u開始輸出u到v中路徑的頂點
					PopStack(&S,&i);
					printf("%s ",G.vertex[i].data);
				}
				printf("\n");
			}else if(visited[p->adjvex]==0){	//假設未找到頂點v且鄰接點未訪問過。則繼續尋找
				visited[p->adjvex]=1;
				parent[p->adjvex]=k;
				PushStack(&S,p->adjvex);
			}
			p=p->nextarc;
		}
	}
}
//返回圖中頂點相應的位置
int LocateVertex(AdjGraph G,VertexType v){
	int i;
	for(i=0;i<G.vexnum;i++)
		if(strcmp(G.vertex[i].data,v)==0)
			return i;
	return -1;
}
//採用鄰接表存儲結構,創建無向圖N
void CreateGraph(AdjGraph *G){
	int i,j,k,w;
	VertexType v1,v2;					/*定義兩個頂點v1和v2*/
	ArcNode *p;
	printf("請輸入圖的頂點數,邊數(以逗號分隔): ");
	scanf("%d,%d",&(*G).vexnum,&(*G).arcnum);
	printf("請輸入%d個頂點的值:",G->vexnum);
	for(i=0;i<G->vexnum;i++)			/*將頂點存儲在頭結點中*/
	{
		scanf("%s",G->vertex[i].data);
		G->vertex[i].firstarc=NULL;		/*將相關聯的頂點置為空*/
	}
	printf("請輸入邊的兩個頂點(以空格作為分隔):\n");
	for(k=0;k<G->arcnum;k++)			/*建立邊鏈表*/
	{
		scanf("%s%s",v1,v2);
		i=LocateVertex(*G,v1);
		j=LocateVertex(*G,v2);
		/*j為入邊i為出邊創建鄰接表*/
		p=(ArcNode*)malloc(sizeof(ArcNode));
		p->adjvex=j;
		p->info=(InfoPtr*)malloc(sizeof(InfoPtr));
		/*將p指向的結點插入到邊表中*/
		p->nextarc=G->vertex[i].firstarc;
		G->vertex[i].firstarc=p;
		/*i為入邊j為出邊創建鄰接表*/
		p=(ArcNode*)malloc(sizeof(ArcNode));
		p->adjvex=i;
		p->info=NULL;
		p->nextarc=G->vertex[j].firstarc;
		G->vertex[j].firstarc=p;
	}
	(*G).kind=UG;
}
//銷毀無向圖G
void DestroyGraph(AdjGraph *G){
	int i;
	ArcNode *p,*q;
	for(i=0;i<G->vexnum;++i)		/*釋放圖中的邊表結點*/
	{
		p=G->vertex[i].firstarc;	/*p指向邊表的第一個結點*/
		if(p!=NULL)					/*假設邊表不為空,則釋放邊表的結點*/
		{
			q=p->nextarc;
			free(p);
			p=q;
		}
	}
	(*G).vexnum=0;					/*將頂點數置為0*/
	(*G).arcnum=0;					/*將邊的數目置為0*/
}
//圖G的鄰接表的輸出
void DisplayGraph(AdjGraph G){
	int i;
	ArcNode *p;
	printf("該圖中有%d個頂點:",G.vexnum);
	for(i=0;i<G.vexnum;i++)
		printf("%s ",G.vertex[i].data);
	printf("\n圖中共同擁有%d條邊:\n",2*G.arcnum);
	for(i=0;i<G.vexnum;i++)
	{
		p=G.vertex[i].firstarc;
		while(p)
		{
			printf("(%s,%s) ",G.vertex[i].data,G.vertex[p->adjvex].data);
			p=p->nextarc;
		}
		printf("\n");
	}
}
void main(){
	AdjGraph G;
	CreateGraph(&G);		/*採用鄰接表存儲結構創建圖G*/
	DisplayGraph(G);		/*輸出無向圖G*/
	BriefPath(G,0,4);		/*求圖G中從頂點a到頂點e的簡單路徑*/
	DestroyGraph(&G);		/*銷毀圖G*/
	system("pause");
}

技術分享

_DataStructure_C_Impl:求圖G中從頂點u到頂點v的一條簡單路徑