图论所有的算法实现。DFS,BFS,Dijkstra,Floyd,Topsort,Kruskal,Prim,

参考资料:

//http://blog.csdn.net/cxllyg/article/details/7606184
//http://2728green-rock.blog.163.com/blog/static/43636790200901211848284/
//http://blog.csdn.net/qiuyoungster/article/details/7846169

//main.c

//http://blog.csdn.net/cxllyg/article/details/7606184
//http://2728green-rock.blog.163.com/blog/static/43636790200901211848284/
//http://blog.csdn.net/qiuyoungster/article/details/7846169
#include
#include"GraphAdjacencyMatrix.h"
//注意程序运行时,选择1,其他的图没有去实现。否则会出现段错误。
int main()
{
	pGraph G=CreateGraph(G);	
	PrintGraph(G);
	char vertex='d';
	char v1='b';
	char v2='c';
	//int w=10;
	/*
	   Degree(G , v);
	   Isadjacency(G, v1, v2);
	   InsertVertex( G ,v);
	   InsertArc( G,v1, v2, w);
	   */
	PrintGraph(G);
	printf("******DFSTraverseInitial******:\n\n");
	DFSTraverseInitial(G);
	printf("input a char: %c ,以该字符为起始节点的深度广度优先遍历\n",vertex);
	//scanf("%c",&v);
	printf("******DFSTraverse******:");
	DFSTraverse(G,vertex);
	printf("******BFSTraverse******:");
	BFSTraverse(G,vertex);
	printf("******MiniSpanTree_Prim******:\n") ;
	MiniSpanTree_Prim(G ,'a');
	printf("\n\n");
	printf("******MiniSpanTree_Kruskal******:\n") ;
	MiniSpanTree_Kruskal(G );
	printf("\n\n");
	
	printf("******Dijkstra 求单源最短路径*******:\n\n");
	int D1[G->vertexnum];
	int Path1[G->vertexnum][G->vertexnum];
	vertex='e';
	ShortestPath_DIJ(G,vertex,D1,Path1);
	int v,w,u;
	for( v=0 ;vvertexnum ;v++)
	{
		if(G->vexs[v]!=vertex) //自己到自己的顶点可以不用输出。
		{
			if(D1[v]vexs[v],v,D1[v]);
				printf("经过的顶点为:" );
				for(w=0 ;wvertexnum ;w++)
				{
					if(Path1[v][w]!=-1)
					{
						printf("%c ",G->vexs[ Path1[v][w] ]) ;
					}
					else
						break;
				}
			}
			else
				printf("源点%c到顶点 %c是不可达的!" ,vertex,G->vexs[v]);
			printf("\n\n");
		}
	}



	printf("*****Floyd 求任意顶点对之间的最短路径******:\n\n");
	int D2[G->vertexnum][G->vertexnum];
	int Path2[G->vertexnum][G->vertexnum][G->vertexnum];
	ShortestPath_FLOYD(G,D2,Path2);

	for( v=0 ;vvertexnum ;v++)
		for( w=0 ;wvertexnum ;w++)
		{
			if(v!=w)
			{
				if(D2[v][w]vexs[v],G->vexs[w],v,w,D2[v][w]);
					printf("经过的顶点为:" );
					for(u=0 ;uvertexnum ;u++)
					{
						if(Path2[v][w][u]!=-1)
						{
							printf("%c ",G->vexs[ Path2[v][w][u] ]) ;
						}
						else
							break;
					}
				}
				else
					printf("顶点%c到顶点 %c是不可达的!" ,G->vexs[v],G->vexs[w]);
				printf("\n\n");
			}
		}


	printf("*****TopSort******:\n\n" );
	int result[G->vertexnum];
	if( TopSort(G,result) )  //需要判断以下,否则由于result[i]未初始化,对于TopSort存在环的情况下,result数组的值是未知的,
		//当调用G->vexs[ result[v] ]会出现越界或者段错误。
	{
		for (v=0 ;vvertexnum; v++)
			printf("%c ",G->vexs[ result[v] ]);
		printf("\n\n");
	}


	Destroy(G);
	return 1;
}



//GraphAdjacencyMatrix.h

#ifndef _GRAPHADJACENCYMATRIX_H_
#define _GRAPHADJACENCYMATRIX_H_


#define MAX_VERTEX_NUM 50  //最大顶点数
#define INFINITY 65535  //65535代表无穷大
#define true  1
#define false 0
#define DEBUG
extern numTree;
extern int  parent[MAX_VERTEX_NUM];

typedef int bool;
typedef int EdgeType ;
typedef char VertexType;
typedef int InfoType ;
typedef int VRType;
//DG是有向图,DN是有向网,UDG是无向图,UDN是无向网
//网和图的区别在于弧有没有权值
typedef  enum {DG,DN,UDG,UDN}GraphKind ;
//弧的定义
typedef struct Arcs
{
	EdgeType adj; //EdgeType是边关系类型
	//对于无权图,用1,0表示是否相邻
	//对于带全图,则为权值类型
	InfoType *info;//弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM] ;

//图的邻接矩阵存储结构

typedef struct GraphAdjacencyMatrix
{
	VertexType vexs[MAX_VERTEX_NUM];
	AdjMatrix arcs;
	int vertexnum;
	int arcsnum;
	GraphKind kind;
}Graph,*pGraph;

bool visited[MAX_VERTEX_NUM] ;


struct closedge   //Prim算法的辅助数组
{
	VertexType adjvex;
	VRType lowcost;
} closedge[MAX_VERTEX_NUM];

typedef struct Edge  //Kruskal算法的辅助数组
{
	int begin;
	int end;
	int weight;
}Edge[MAX_VERTEX_NUM] ;

pGraph CreateGraph();
pGraph CreateDN();
pGraph CreateDG();
pGraph CreateUDG();
pGraph CreateUDN();
pGraph CreateAOE();

int  Degree(pGraph G ,VertexType v);
int  Isadjacency(pGraph G, VertexType v1, VertexType v2);
bool InsertVertex(pGraph G ,VertexType v);
bool InsertArc(pGraph G,VertexType v1, VertexType v2, int w);

int  Locate(pGraph G , char ch);
void PrintGraph(pGraph G);

void DFSTraverse(pGraph G, char v);
void DFSTraverseInitial(pGraph G);
void DFS(pGraph G ,int i);

void BFS(pGraph G ,int location);
void BFSTraverse(pGraph G ,char v);

void MiniSpanTree_Prim(pGraph G ,VertexType v);
int minimum(pGraph G,struct closedge  closedge[]);

void MiniSpanTree_Kruskal(pGraph G);
int cmpstruct(const void * a, const void *b);
bool IsConnected( Edge edge, int k);

void MiniSpanTree_Sollin(pGraph G );
void Visit(char ch);

bool TopSort(pGraph G, int result[]) ;
void ShortestPath_DIJ(pGraph G,char vertexs,int D[],bool Path[][G->vertexnum]);
void ShortestPath_FLOYD(pGraph G,int D[][G->vertexnum],bool Path[][G->vertexnum][G->vertexnum]);

#endif

//GraphAdjacencyMatrix.c

#include
#include
#include"GraphAdjacencyMatrix.h"
#include"UnionFind.h"
#include"LinkQueue.h"


int Degree(pGraph G ,VertexType v)
{
	int n=Locate(G ,v) ;
	if(n==-1)
	{
		printf("dont exist the vertexs %c\n",v);
		return -1;
	}
	else
	{  
		int count=0 ,i;
		if(G->kind==DN) //对于其他种类的图,暂时不写,这样的话,可扩展性强
		{
			for (i=0 ;ivertexnum ;i++ )
			{
				if(G->arcs[n][i].adj !=0 && G->arcs[n][i].adj !=INFINITY)
					count++;
			}

			for (i=0 ;ivertexnum ;i++)
			{
				if(G->arcs[i][n].adj !=0 && G->arcs[i][n].adj !=INFINITY )
					count++;
			}

			return count ;
		}
	}
}

/*
 *判断两个顶点是否相邻,如果没有该顶点返回-1;
 *否则,如果是带权的网返回,权值,通过判断返回值来判断是否相邻,例如权值为INFINITY,0则为不相邻;
 *   如果是无权的图,则,返回值为1,为相邻;为0为不相邻
 * */
int Isadjacency(pGraph G, VertexType v1, VertexType v2)
{
	int m=Locate(G,v1);
	int n=Locate(G,v2);
	if(m==-1 || n==-1)
		return -1;
	return G->arcs[m][n].adj;

}
/*
 *
 *插入一个顶点
 * */
bool InsertVertex(pGraph G ,VertexType v)
{
	int m=Locate(G,v);
	if( m!=-1)
	{
		printf("the same vertex %c exist\n",v);
		return false;
	}
	else
	{
		if(G->kind==DN)
		{
			int i;
			G->vexs[G->vertexnum] =v;
			for(i=0; ivertexnum ; i++)
				G->arcs[G->vertexnum][i].adj =INFINITY;

			for(i=0; i< G->vertexnum ; i++)
				G->arcs[i][G->vertexnum].adj=INFINITY;
			G->arcs[G->vertexnum][G->vertexnum].adj=0;
			G->vertexnum++;
			return true;
		}
	}
}

/*
 *从输入的顶点开始遍历
 * */
void DFSTraverse(pGraph G, char v)
{
	int i;
	int m=Locate(G,v);
	if(m==-1)
		printf("Graph doesn't have the vertexs %c\n",v);
	for (i =0;ivertexnum ;i++)
		visited[i]=false;
	DFS(G,m);
	for(i=0 ; i< G->vertexnum ; i++ )
	{
		if( !visited[i])
		{
			DFS(G,i);
		}
	}
	printf("\n");
}

/*
 * 每次从第一个顶点开始遍历
 * */
void DFSTraverseInitial(pGraph G) //每次对第一个第一个节点进行遍历
{
	int i;
	for( i=0 ;i< G->vertexnum ;i++)
		visited[i]=false;

	for( i=0 ;i vertexnum ; i++)  //对未访问的顶点递归调用DFS,如果是连通图则只执行一次
	{
		if(! visited[i])
			DFS(G ,i);
	}
	printf("\n");
}

void DFS(pGraph G ,int i)
{
	visited[i]=true;
	Visit(G->vexs[i]);
	int j;
	for( j=0 ;j< G->vertexnum ;j++)
	{
		if(G->arcs[i][j].adj !=INFINITY && G->arcs[i][j].adj !=0 && !visited[j])
			DFS(G, j);
	}
}

void BFSTraverse(pGraph G ,char v)
{
	int i;
	int m=Locate(G,v);
	if(m==-1)
		printf("Graph doesn't have the vertexs %c\n",v);
	for ( i=0 ;ivertexnum ;i++)
		visited[i]=false;

	BFS(G,m);
	for( i=0 ;i< G->vertexnum ;i++)
	{
		if(!visited[i])
			BFS(G, i);
	}
	printf("\n");
}

void BFS(pGraph G ,int location)
{
	pLinkQueue q=InitLinkQueue();
	EnLinkQueue(q,location);
	visited[location]=true;
	while(!IsLinkQueueEmpty(q) )
	{
		int i;
		DeLinkQueue(q, &i);
		Visit(G->vexs[i]);
		//visited[i]=true;  //如果是每次出队时,表示遍历过,会使有些元素重复入队,
		//从而遍历的结果使有些结点重复输出,所以应该时每次入队时,表示遍历过
		int j;
		for( j=0;j< G->vertexnum ;j++)
		{
			if(G->arcs[i][j].adj !=INFINITY && G->arcs[i][j].adj !=0 && !visited[j])
			{
				EnLinkQueue(q,j);
				visited[j]=true;
			}
		}

	}
	DestroyLinkQueue(q);

}

/*
 *无向图的最小生成树Prim算法
 * */


void MiniSpanTree_Prim(pGraph G ,VertexType v)
{
	//int lowcost[G->vertexnum];
	int m=Locate(G,v);
	if(m==-1)
	{
		printf(" Graph doesn't have the vertexs %c\n" ,v);
		return ;
	}
	int i;
	for( i=0 ; i< G->vertexnum ;i++)
	{
		if(i != m)
		{
			closedge[i].adjvex=G->vexs[m];
			closedge[i].lowcost=G->arcs[i][m].adj;
		}
	}

	int totalWeight=0;//表示最小生成树的权值大小
	closedge[m].lowcost=0 ;//初始化,U={u}

for(i=1; i<=G->vertexnum-1 ;i++)
{
	int k=minimum(G, closedge);
	printf("%c %d %c\n",closedge[k].adjvex,closedge[k].lowcost ,G->vexs[k]);
	totalWeight+=closedge[k].lowcost;//
	closedge[k].lowcost=0 ;  //第k顶点并入U集

	int j;
	for( j=0 ;jvertexnum ;j++)
	{
		if(G->arcs[k][j].adj < closedge[j].lowcost)
		{
			closedge[j].adjvex=G->vexs[k];
			closedge[j].lowcost=G->arcs[k][j].adj ;
		}
	}
} 

printf("MiniSpanTree_Prim 求得的最小权值是%d\n",totalWeight); 

}

int minimum(pGraph G,struct closedge  closedge[])
{ 
	int i=0;
	int temp=INFINITY;
	int index;
	for( i=0 ;i vertexnum ;i++)
	{
		if( closedge[i].lowcost>0 && closedge[i].lowcost !=INFINITY  && closedge[i].lowcost  (* ( struct Edge *)b).weight ? 1:-1;
}

int GetEdgeInformation(pGraph G, Edge edge)
{
	int i,j;
	int undirectedEdgeNum=0;  
	for(i=0 ; i< G->vertexnum ;i++)  //获取每条无向边的信息
		for(j=i+1; jvertexnum ;j++)
		{
			if(G->arcs[i][j].adj!=INFINITY)
			{
				edge[undirectedEdgeNum].begin=i;
				edge[undirectedEdgeNum].end=j;
				edge[undirectedEdgeNum].weight=G->arcs[i][j].adj;
				undirectedEdgeNum++;
			}
		}
	return undirectedEdgeNum;
}
void MiniSpanTree_Kruskal(pGraph G)
{
	Edge edge;
	int undirectedEdgeNum=GetEdgeInformation(G, edge); //无向边的数目(如两个顶点a-b存在一条有向边,只记录一个a-b而b-a不记录)
	//对无向图的所有边按权值排序
	qsort(edge,undirectedEdgeNum ,sizeof(edge[0]),cmpstruct); 

	int k=0;  //k表示选择哪一条边,进行Kruskal
	int totalWeight=0; //表示最小生成树的权值大小
	int edgenum=0; //表示通过Kruskal算法已经加入边的数目
	int flag=0;
	MakeSet(G->vertexnum) ; //集合的初始化,每个结点刚开始时,独立的属于一个集合
	int i;
	for(i=1;ivexs[ edge[k].begin ] ,edge[k].weight, G->vexs[ edge[k].end ]);
			totalWeight+=edge[k].weight;
			edgenum++;
		}
		else
		{
			//表示加入该边,会形成回路
		}
		k++;
		if(edgenum == G->vertexnum-1) //最小生成树条件:边数=顶点数-1  
		{  
			flag = 1;  
			break;  
		}  


	}

	if(flag) 
		printf("MiniSpanTree_Kruskal 求得的最小权值是%d\n",totalWeight); 
	else 
		printf("生成最小生成树失败!该网非连通!\n"); 

}

bool IsConnected( Edge edge, int k)
{
	if( Find(edge[k].begin) == Find(edge[k].end) )
		return true;
	else
	{
		Union(edge[k].begin, edge[k].end );
		return false;
	}
}





/*
 * Dijkstra 算法求单源最短路径,即某个顶点到图中任意顶点的最短距离
 * */
// v0(vertexs) 表示源点
// D[i]表示源点v0到顶点i的最短路径长度 
// Path[v][]表示源点v0到达顶点v的路径,若Path[v][w]=true,表示顶点w是从v0到v的最短路径上的顶点
// final[v]=true表示求得了从v0到v的最短路径,即把v加入了集合S中

void ShortestPath_DIJ(pGraph G,char vertexs,int D[],int Path[][G->vertexnum])
{
	bool final[G->vertexnum];
	int v0=Locate(G,vertexs);
	if(v0==-1)
	{
		printf("the Graph don't have the vertexs %c",v0);
		return;
	}
	//初始化工作
	int v,w;
	for(v=0 ; vvertexnum ;v++)
	{
		final[v]=false;
		D[v]=G->arcs[v0][v].adj;
		for(w=0 ; wvertexnum ;w++)
		{
			Path[v][w]=-1;
		}
		if(D[v] vertexnum; i++)
	{
		int min=INFINITY;
		for(w=0 ; wvertexnum ;w++)
		{
			if( !final[w])
			{
				if(D[w] vertexnum ;w++)
		{
			if( !final[w] && min+G->arcs[v][w].adj arcs[v][w].adj;
				int j;
				for(j=0 ; j< G->vertexnum ;j++)
				{
					if(Path[v][j]!=-1)
						Path[w][j]=Path[v][j];
					else
						break;
				}
				Path[w][j++]=w; //P[w]=P[v]+P[w]
			}
		}
	}
}

//弗洛伊德算法求每一对顶点间的最短路径

void ShortestPath_FLOYD(pGraph G,int D[][G->vertexnum],int Path[][G->vertexnum][G->vertexnum])
{
	//p[v][w][i]表示当前求得的顶点v到顶点w的最短路径中的第i+1个顶点,因为下标从0开始
	//D[v][w]表示顶点v到顶点w的最短路径长度。
	//初始化工作
	int v,w,u;
	for(v=0 ;vvertexnum ;v++)
		for(w=0 ;wvertexnum ;w++)
		{
			D[v][w]=G->arcs[v][w].adj;
			for(u=0; uvertexnum ;u++)
				Path[v][w][u]=-1;
			if( D[v][w]vertexnum ;u++)
		for(v=0 ;vvertexnum ;v++)
			for(w=0 ;wvertexnum ;w++)
			{
				if(D[v][u] < INFINITY && D[u][w] < INFINITY && D[v][u]+D[u][w] < D[v][w])
				{
					//更新D
					D[v][w]=D[v][u]+D[u][w];
					int i;
					//更新Path
					for(i=0 ;ivertexnum ;i++)
					{
						if(Path[v][u][i]!=-1)
							Path[v][w][i]=Path[v][u][i];
						else
							break;
					}
					int j;
					for(j=1; jvertexnum ;j++ )
					{
						if(Path[u][w][j]!=-1)
							Path[v][w][i++]=Path[u][w][j];
						else
							break;
					}
				}
			}
}
/*
 *TopSort思想:
 *(1) 判断顶点是否有前驱
 *(2) 删除顶点和关联与该顶点的所有边 注:该方法没有采用删除的策略,而是通过visit数组来实现,
 *     即把visit[i]置为true,此时不对它相关联的边访问即可
 * 注:要对于是否存在TopSort即有没有环进行判断
 * */
bool TopSort(pGraph G, int result[]) //result[] :把TopSort结果依次存入
{
	int v,w;
	int i;
	bool visit[G->vertexnum];//顶点是否已经已经遍历过
	for(i=0 ;ivertexnum ;i++)
		visit[i]=false;
	int count=0; //如果AOE网顶点为n,每个顶点到Vk都不存在有向边的时候,则表示该顶点无前驱。
	//count表示每一顶点到Vk无有向边的个数,此时count=n-1即无前驱
	int number=G->vertexnum; //待遍历顶点的个数
	i=0;
	for(v=0 ; vvertexnum ;v++)
	{
		if( !visit[v])
		{
			count=0;
			for( w=0 ;wvertexnum ;w++)//判断顶点是否有前驱
			{
				if(!visit[w])
				{
					if(w==v)
						continue;
					else if( G->arcs[w][v].adj==INFINITY )
						count++;
					else
						break;
				}
			}
			if(count==number-1)//此时该顶点没有前驱,可以输出
			{
				visit[v]=true;
				number--;
				result[i++]=v;
				v=0;  //每次加入一个顶点,得重新开始
			}

		}
	}
	if(ivertexnum)
	{
		printf("该AOE网存在环,不存在TopSort\n");
		return false;
	}
	return true;
}

void Visit(char ch)
{
	printf("%c ",ch);
}

/*
 *
 *在顶点v1和v2之间插入一个权值为w的弧
 * */
bool InsertArc(pGraph G,VertexType v1, VertexType v2, int w)
{
	int m=Locate(G,v1);
	int n=Locate(G,v2);
	if(m==-1 || n==-1)
	{
		printf("don't exist the vertexs %c or %c",v1,v2);
		return false;
	}
	if(G->arcs[m][n].adj==INFINITY || G->arcs[m][n].adj==0)
	{
		G->arcs[m][n].adj=w;
		G->arcsnum++;
		return true;
	}
	else
	{
		printf("the arcs exist\n");
		return false;
	}
}
/*
 *创建一个图,然后选择创建什么样的图
 * */
pGraph  CreateGraph()
{
	printf("0:DG  1:DN  2:UDG  3:UDN  4:AOE\n");
	printf("please input the Graph's kind:");
	int kind;
	scanf(" %d",&kind);
	switch(kind)
	{
		case 0: return CreateDG();

		case 1: return CreateDN();

		case 2: return CreateUDG();

		case 3: return CreateUDN();

		case 4: return CreateAOE(); //其实主要为了测试,添加上去的数据

		default:
				printf("the input is error\n");
				CreateGraph();
	}
}

/*
 *创建一个有向网
 * */
#if 0
pGraph CreateDN( )
{

	char buf[1024];  //程序的鲁壮性较好,当输入输入出现错误时,把行缓冲中的数据按照要求读入。
                         //fflush在linux下主要指定输出流,在windows下可以,那是因为winwods下VC做了封装
	pGraph G=(pGraph) malloc(sizeof(Graph)) ;
	G->kind=1;
	printf("please input the vertexnum and arcsnum:");
	scanf("%d %d",& G->vertexnum,& G->arcsnum) ;
	fgets(buf,1024,stdin);
	printf("input the vertexs:");
	int i,j;

	for(i=0 ; ivertexnum ;i++ )
		scanf("%c",& G->vexs[i]) ;
	fgets(buf,1024,stdin);
	//setbuf(stdin,NULL);  用这个替换上面的不行,好像有一个%*c忘了,查查
	char v1 ,v2;
	int w;
	//弧权值的初始化
	for(i=0;ivertexnum ;i++)
		for(j=0;jvertexnum ;j++)
		{
			if(i!=j)
			{
				G->arcs[i][j].adj=INFINITY;
				G->arcs[i][j].info=NULL;
			}
			else
			{
				G->arcs[i][j].adj=0;
				G->arcs[i][j].info=NULL;
			}
		}
	for(i=0 ; iarcsnum ;i++)
	{
		printf("input the DN的每个顶点i,顶点j和权值\n" );
		scanf("%c %c %d",&v1,&v2,& w);
		fgets(buf,1024,stdin);
		int m=Locate(G,v1);
		int n=Locate(G,v2);
		if(m==-1 || n==-1)
		{
			printf("input is error\n");
		}

		G->arcs[m][n].adj=w;
	}
	return G;

}
#endif

//测试用例
pGraph CreateDN( )
{

	pGraph G=(pGraph) malloc(sizeof(Graph)) ;
	G->kind=1;
	G->vertexnum=6; //6
	G->arcsnum=20; //20

	int i,j;
	for(i=0 ; ivertexnum ;i++ )
		G->vexs[i]='a'+i ;
	char v1 ,v2;
	int w;
	//弧权值的初始化
	for(i=0;ivertexnum ;i++)
		for(j=0;jvertexnum ;j++)
		{
			if(i!=j)
			{
				G->arcs[i][j].adj=INFINITY;
				G->arcs[i][j].info=NULL;
			}
			else
			{
				G->arcs[i][j].adj=0;
				G->arcs[i][j].info=NULL;
			}
		}
	// 20条边
	/*
	   a b 6
	   b a 6
	   a d 5
	   d a 5
	   a c 1
	   c a 1
	   b c 5
	   c b 5
	   d c 5
	   c d 5
	   b e 3
	   e b 3
	   c e 6
	   e c 6
	   c f 4
	   f c 4
	   d f 2
	   f d 2
	   e f 6
	   f e 6
	   */
	G->arcs[0][1].adj=6 ;
	G->arcs[1][0].adj=6 ;
	G->arcs[0][3].adj=5 ;
	G->arcs[3][0].adj=5 ;
	G->arcs[0][2].adj=1 ;
	G->arcs[2][0].adj=1 ;
	G->arcs[1][2].adj=5 ;
	G->arcs[2][1].adj=5 ;
	G->arcs[2][3].adj=5 ;
	G->arcs[3][2].adj=5 ;
	G->arcs[1][4].adj=3 ;
	G->arcs[4][1].adj=3 ;
	G->arcs[2][4].adj=6 ;
	G->arcs[4][2].adj=6 ;
	G->arcs[2][5].adj=4 ;
	G->arcs[5][2].adj=4 ;
	G->arcs[3][5].adj=2 ;
	G->arcs[5][3].adj=2 ;
	G->arcs[4][5].adj=6 ;
	G->arcs[5][4].adj=6 ;
	return G;

}

//测试用例
pGraph CreateAOE( )
{

	pGraph G=(pGraph) malloc(sizeof(Graph)) ;
	G->kind=1;
	G->vertexnum=6; //6
	G->arcsnum=20; //20

	int i,j;
	for(i=0 ; ivertexnum ;i++ )
		G->vexs[i]='a'+i ;
	char v1 ,v2;
	int w;
	//弧权值的初始化
	for(i=0;ivertexnum ;i++)
		for(j=0;jvertexnum ;j++)
		{
			if(i!=j)
			{
				G->arcs[i][j].adj=INFINITY;
				G->arcs[i][j].info=NULL;
			}
			else
			{
				G->arcs[i][j].adj=0;
				G->arcs[i][j].info=NULL;
			}
		}
	//8条边,用于AOE网TopSort的测试
	/*
	   a d 5
	   d c 5
	   d f 2
	   b c 5
	   b e 3
	   c e 6
	   c f 4
	   e f 6
	   */

	G->arcs[0][3].adj=5 ;
	G->arcs[3][2].adj=5 ;
	G->arcs[3][5].adj=2 ;
	G->arcs[1][2].adj=5 ;
	G->arcs[1][4].adj=3 ;
	G->arcs[2][4].adj=6 ;
	G->arcs[2][5].adj=4 ;
	G->arcs[4][5].adj=6 ;

	return G;

}


pGraph CreateDG()
{
}
pGraph CreateUDG()
{
}
pGraph CreateUDN()
{
}

/*
 *定位顶点ch在顶点数组的位置
 * */
int Locate(pGraph G , char ch)
{
	int i;
	for( i=0 ;ivertexnum ;i++)
	{
		if( G->vexs[i]==ch)
			return i;
	}
	return -1;

}
/*
 *销毁图,释放图的空间
 * */
void Destroy(pGraph G) 
{
	free(G);
}

/*
 *图的邻接矩阵的输出
 * */
void PrintGraph(pGraph G)
{
	int i,j;
	for(i=0;i< G->vertexnum ;i++)
	{
		for( j=0 ;j< G->vertexnum ;j++)
		{
			printf("  %d  ", G->arcs[i][j].adj);		
		}
		printf("\n");
	}
}



//LinkQueue.h

#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_
//队列的链式存储结构

//当CHAR定义时,用字符的处理模式
//当CHAR没有被定义时,采用整数处理模式
#define INT
#ifdef INT
//数据类型的定义
typedef int DataType;
#else
typedef char Datatype;
#endif


//队列节点存储结构
typedef struct Node
{
	DataType data;
	struct Node *next;
} Node, *pNode;

//队列存储结构
typedef struct Queue
{
	pNode front;
	pNode rear;
	int queuesize;
} LinkQueue, *pLinkQueue;

pLinkQueue InitLinkQueue();
int  IsLinkQueueEmpty(pLinkQueue q);
int  GetLinkQueueLength(pLinkQueue q);
void EnLinkQueue(pLinkQueue q, DataType x);
void DeLinkQueue(pLinkQueue q,DataType *x);
int  GetHead(pLinkQueue q,DataType *x);
void print(DataType data);
void LinkQueueTraverse(pLinkQueue q, void (*Visit) (DataType data) );
void ClearLinkQueue(pLinkQueue q);
void DestroyLinkQueue(pLinkQueue q);

#endif

LinkQueue.c

#include
#include
#include
#include"LinkQueue.h"


pLinkQueue InitLinkQueue()
{
	pLinkQueue q=(pLinkQueue ) malloc(sizeof(LinkQueue)) ;
	if(!q)
	{
		q->front=NULL;
		q->rear=NULL;
		q->queuesize=0;
	}
	return q;
}

int  IsLinkQueueEmpty(pLinkQueue q)
{
	if(q->queuesize ==0)
		return 1;
	else
		return 0;
}

int GetLinkQueueLength(pLinkQueue q)
{
	return q->queuesize;
}

void EnLinkQueue(pLinkQueue q, DataType x)
{
	if( q )
	{
		pNode p=(pNode ) malloc(sizeof(Node) ) ;
		p->data=x;
		p->next=NULL;

		if(q->queuesize==0)   //刚开始时队列为空时,对队头指针进行赋值
		{
			q->front=p;
			q->rear=p;
		}
		else
		{
			q->rear->next=p;
	       		q->rear=p;
	        }	
         	q->queuesize++;
		
	}
}

void DeLinkQueue(pLinkQueue q,DataType *x)
{
	if(q->queuesize==0)
	{
		printf("the queue is null,can't get anything\n"); 
	}
	else
	{
		if(q->front==q->rear) //只有一个节点时,无节点的情况上面已经考虑了
		{
			*x=q->front->data;
			free(q->front);
			q->front=NULL;
			q->rear=NULL;
		}
		else
		{
			pNode p=q->front;
			*x=p->data;
			q->front=q->front->next;
			free(p);
		}
		q->queuesize--;

	}
}

int   GetHead(pLinkQueue q,DataType *x)
{
	if(q->queuesize==0)
		return 0 ;
	else
	{
		*x= q->front->data;
		return 1 ;
	}

}

void print(DataType data)
{
	printf("%d ",data);
}

void LinkQueueTraverse(pLinkQueue q, void (*Visit) (DataType data) )
{
	if(!q)
		exit(-1);
	pNode p=q->front ;
        if(!p)
            {
              printf("the LinkQueue is null\n");
              return ;
            }
	while(p)
	{
		Visit(p->data);
		p=p->next ;
	}

}

void ClearLinkQueue(pLinkQueue q)
{
	DataType data;
	while(q->queuesize)
	{
		DeLinkQueue(q,&data);

	}
}

void DestroyLinkQueue(pLinkQueue q)
{
	if(q->queuesize!=0)
		ClearLinkQueue(q) ;
	free(q);
}


//UnionFind.h

#ifndef _UNIONFIND_H_
#define _UNIONFIND_H_

void MakeSet(int n);
int Find(int i);
void Union(int i ,int j);

#endif

//UnionFind.c

//并查集数据结构主要用于求连通子图,最小生成树的kruskal算法和最近公共祖先(Least Common Ancestors,LCA,等价类问题)
//前提条件:任意两个集合不能相交.
// (1) 不相交集合的并
// (2)  查找某个集合元素所属的集合
#include"UnionFind.h"
#define MAX_VERTEX_NUM 50  //最大顶点数
int parent[MAX_VERTEX_NUM] ;
int numTree;


/*
 *创建集合,并对集合初始化
 * */
void MakeSet(int n)
{
	int i;
	for( i=0 ;i=0 )
		i=parent[i]; //此时退出循环找到了根节点i
	while(parent[p]>=0) //使路径上的结点都指向根节点
	{
		int t=parent[p];
		parent[p]=i;
		p=t;
	}
	return i;
}


void Union(int i ,int j)
{
	int pID=Find(i);
	int qID=Find(j);
	if(pID==qID)
		return ;
	else
	{
		if(parent[pID] < parent[qID]) //如 -9 ,-5
		{
			parent[pID]=parent[pID]+parent[qID];
			parent[qID]=pID;
		}

		else
		{
			parent[qID]=parent[pID]+parent[qID];
			parent[pID]=qID;

		}
                numTree--;
	}
}


你可能感兴趣的:(Data,Struct,Algorithm,C)