图的各类算法实现

Posted cjj2503

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的各类算法实现相关的知识,希望对你有一定的参考价值。

图的各类算法实现

实验内容:
设图结点的元素类型为char,建立一个不少于8个顶点的带权无向图G,实现以下图的各种基本操作的程序:
① 用邻接矩阵作为储结构存储图G并输出该邻接矩阵;
② 按DFS算法输出图G中顶点的遍历序列;
③ 按BFS算法输出图G中顶点的遍历序列;
④ 按Prime算法从某个指定的顶点出发输出图G的最小生成树

输入样例:
a b c d e f g h i j k l //顶点数据
0 1 10 //边的数据 (v1 v2 权值)
0 2 4
0 3 30
1 4 11
1 5 20
2 5 5
2 6 60
3 7 55
4 8 8
4 9 100
6 9 34
6 11 19
8 9 9
9 10 8

测试数据

input1.txt

a b c d e f g h i j k l
0  1   10
0  2   4
0  3   30
1  4   11
1  5   20
2  5   5
2  6   60
3  7   55
4  8   8
4  9   100
6  9   34
6  11  19
8  9   9
9  10  8

output1.txt

a b c d e f g h i j k l
0    10   4    30   1000 1000 1000 1000 1000 1000 1000 1000
10   0    1000 1000 11   20   1000 1000 1000 1000 1000 1000
4    1000 0    1000 1000 5    60   1000 1000 1000 1000 1000
30   1000 1000 0    1000 1000 1000 55   1000 1000 1000 1000
1000 11   1000 1000 0    1000 1000 1000 8    100  1000 1000
1000 20   5    1000 1000 0    1000 1000 1000 1000 1000 1000
1000 1000 60   1000 1000 1000 0    1000 1000 34   1000 19
1000 1000 1000 55   1000 1000 1000 0    1000 1000 1000 1000
1000 1000 1000 1000 8    1000 1000 1000 0    9    1000 1000
1000 1000 1000 1000 100  1000 34   1000 9    0    8    1000
1000 1000 1000 1000 1000 1000 1000 1000 1000 8    0    1000
1000 1000 1000 1000 1000 1000 19   1000 1000 1000 1000 0
a b e i j g c f l k d h
a b c d e f g h i j l k
a c 4
c f 5
a b 10
b e 11
e i 8
i j 9
j k 8
a d 30
g j 34
g l 19
d h 55

代码体
AdjMGraph.h

/*
设图结点的元素类型为char,建立一个不少于8个顶点的带权无向图G,实现以下图的各种基本操作的程序:
① 用邻接矩阵作为储结构存储图G并输出该邻接矩阵;
② 按DFS算法输出图G中顶点的遍历序列;
③ 按BFS算法输出图G中顶点的遍历序列;
④ 按Prime算法从某个指定的顶点出发输出图G的最小生成树;
*/
#ifndef ADJMGRAPH_H
#define ADJMGRAPH_H


#include "SeqList.h"//顺序表头文件
#include "SeqCQueue.h"//顺序循环队列
#include "SeqList.h"  //顺序堆栈


#define MaxVertices 50
#define MaxWeight 1000

typedef char VDataType;

typedef struct{
	SeqList Vertices;//存放顶点的顺序表
	int edge[MaxVertices][MaxVertices];//存放边的邻接矩阵
	int numOfEdges;//边的个数
}AdjMGraph;//图的结构体定义


//最小生成树的存储结构体
typedef struct{
	int v1;  
	int v2;
	int weight;
}MinSpanTreeEage;

void AdjInitiate(AdjMGraph*G,int n);

int  InsertVertex(AdjMGraph*G,VDataType vertex);

int  DeleteEdge(AdjMGraph*G,int v1,int v2);

int  InsertEdge(AdjMGraph*G,int v1,int v2,int weight);

int  GetFirstVex(AdjMGraph G,int c);

int  GetNextVex(AdjMGraph G,int v1,int v2);

void CreateGraph(AdjMGraph* G, FILE* file );

void PrintGraph(AdjMGraph G );

void DepthFSearch(AdjMGraph G,int v ,int visited[],VDataType* result,int* count );

void BroadFSearch(AdjMGraph G,int v,int visited[],VDataType* result,int* count );

void Prime(AdjMGraph G,MinSpanTreeEage closeVertex[]);

#endif

SeqCQueue.h

#ifndef SEQCQUEUE_H
#define SEQCQUEUE_H
#include <stdio.h>
#include <stdlib.h>


#define MaxQueueSize 100
typedef int QDataType;
//顺序循环队列的结构体
typedef struct Queue{ 

	QDataType queue[MaxQueueSize];
	int rear;  //队尾指针
	int front;  //队头指针
	int count;  //计数器
	
} SeqCQueue; 

void QueueInitiate(SeqCQueue *Q);

int  QueueNotEmpty(SeqCQueue Q);

int  QueueAppend(SeqCQueue *Q, QDataType x);

int  QueueDelete(SeqCQueue *Q, QDataType *d);

int  QueueGet(SeqCQueue Q, QDataType *d);
 


#endif

SeqList.h

#ifndef SEQLIST_H
#define SEQLIST_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define MaxSize 100
typedef char ItemType;

typedef struct List{

    ItemType list[MaxSize];	
	int length;
} SeqList;

void ListInitiate(SeqList *L);
int ListInsert(SeqList *L, int i, ItemType x);
int ListDelete(SeqList *L, int i, ItemType *x);
int ListGet(SeqList L, int i, ItemType *x);
#endif

SeqStack.h

#ifndef SEQSTACK_H
#define SEQSTACK_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define MaxStackSize 100

typedef int DataType;

typedef struct Stack
{	
	DataType stack[MaxStackSize];			
	int top;
} SeqStack;


void StackInitiate(SeqStack *S);	

int StackNotEmpty(SeqStack S);

int StackPush(SeqStack *S, DataType x);


int StackPop(SeqStack *S, DataType *d);

int StackTop(SeqStack S, DataType *d);

#endif

SeqCQueue.c

#include "SeqCQueue.h"

//初始化QueueInitiate(Q)
void QueueInitiate(SeqCQueue *Q)
{
	Q->rear = 0;		
	Q->front = 0;
	Q->count = 0;
}


//判断循环队列Q非空否,非空则返回1,否则返回0
int QueueNotEmpty(SeqCQueue Q)
{
	if(Q.count != 0)	return 1;
	else return 0;
}


//把数据元素值x插入顺序循环队列Q的队尾,成功返回0,失败返回-1
int QueueAppend(SeqCQueue *Q, QDataType x)
{
	if(Q->count > 0 && Q->rear == Q->front)
	{	
		printf("The Queue is full! \\n");
		return -1;
	}
	else
	{	
		Q->queue[Q->rear] = x;
		Q->rear = (Q->rear + 1) % MaxQueueSize;
		Q->count++;
		return 0;
	}
}


//删除顺序循环队列Q的队头元素并赋值给d,成功则返回0,失败返回-1
int QueueDelete(SeqCQueue *Q, QDataType *d)
{
	if(Q->count == 0){
		printf("The Queue is empty! \\n");
		return -1;
	}
	else
	{	*d = Q->queue[Q->front];
		Q->front = (Q->front + 1) % MaxQueueSize;
		Q->count--;
		return 0;
	}
}

//取队头数据元素 QueueGet(Q, d)
int QueueGet(SeqCQueue Q, QDataType *d)
{
	if(Q.count == 0)
	{
		printf("The Queue is empty!\\n");
		return -1;
	}
	else
	{
		*d = Q.queue[Q.front];
		return 0;
	}
}

SeqList.c

#include "SeqList.h"

//初始化   
void ListInitiate(SeqList *L)	 
{	
	L->length= 0;  /*定义初始数据元素个数*/                  
}

//求当前数据元素个数  
int ListLength(SeqList L)		 
{	
	return L.length;
} 

//在顺序表L的第i(0≤i ≤ length-1)个位置插入数据元素x
//插入成功返回0,失败返回-1
int ListInsert(SeqList *L, int i, ItemType x)
{	int j;
	if(L->length >MaxSize)
	{
		printf("The list is full!");
		return -1;
	}
	else if(i<0||i>L->length)
	{
		printf("The parameter i is illegal!\\n");
		return -1;
	}  else 
	     {
		for(j = L->length; j > i; j--)
    	    		L->list[j] = L->list[j-1];             	 /*依次后移*/
    	L->list[i] = x;
		L->length ++;
		return 0;
	   }
}

//删除顺序表L中位置i(0≤i ≤ length-1)上的数据元素并保存到x中
//删除成功返回0,删除失败返回-1   
int ListDelete(SeqList *L, int i, ItemType *x)	

{	int j;
	if(L->length <=0)
	{
		printf("The list is empty!");
		return -1;
	}
	else if(i<0||i>L->length-1)
	{
		printf("The parameter i is illegal!");
		return -1;
	}  else 
		{
			*x = L->list[i];		/*保存删除的元素到x中*/
			for(j=i+1; j<=L->length-1; j++)
       			L->list[j-1] = L->list[j];      	/*依次前移*/
			L->length--;			/*数据元素个数减1*/
			return 0;
		}
}

//取数据元素,成功返回0,失败返回-1     
int ListGet(SeqList L, int i, ItemType *x)
{	if(i < 0 || i > L.length-1)
	{
	    printf("The parameter i is illegal!");
	    return -1;
	}
	else
	{
	    *x = L.list[i];
	    return 0;
	}
}

SeqStack.c

#include "SeqStack.h"

//初始化   
void StackInitiate(SeqStack *S)	
{
	S->top = -1;		
}

//非空否   
int StackNotEmpty(SeqStack S)
{
	if(S.top < 0)	return 0;
	else return 1;
}


//把数据元素值x存入顺序堆栈S中,入栈成功则返回0,失败返回-1
int StackPush(SeqStack *S, DataType x)
{
	if(S->top > MaxStackSize-1)
	{	
		printf("Stack is full!");	
		return -1;
	}
	else
	{	
	    S->top ++;
		S->stack[S->top] = x;
		
		return 0;
	}
}

//出栈 ,成功则返回0,失败返回-1  
int StackPop(SeqStack *S, DataType *d)
{
	if(S->top < 0)
	{	
		printf("The stack is empty!");
		return -1;
	}
	else
	{	

		*d = S->stack[S->top];
		S->top --;
		return 0;
	}
}
//取栈顶数据元素 
int StackTop(SeqStack S, DataType *d)
{
	if(S.top <0)
	{	
		printf("The stack is empty!");
		return -1;
	}
	else
	{	*d = S.stack[S.top];
		return 0;
	}
}

AdjMGraph.c

#include "AdjMGraph.h"
//初始化最多可以存放n个顶点的顶点顺序表和邻接矩阵
void AdjInitiate(AdjMGraph*G,int n){
	int i,j;
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			if(i==j)G->edge[i][j]=0;
			else G->edge[i][j]=MaxWeight;
		}
	}
	G->numOfEdges=0;
	ListInitiate(&G->Vertices);
}

//在图中插入顶点vertex,顶点序号自动分配,成功返回0,失败返回-1
int InsertVertex(AdjMGraph*G, VDataType vertex){

	return ListInsert(&(G->Vertices),G->Vertices.length,vertex);
	
}

//在图中插入边<v1,v2>,v1,v2为顶点序号,权值为weight,成功返回0, 失败返回-1
int InsertEdge(AdjMGraph*G,int v1,int v2,int weight){

	if(v1<0||v1>=G->Vertices.length||v2<0||v2>=G->Vertices.length){
		printf("parameter v1 or parameter v2 is illegal!",v1,v2);
		return -1;
	}
	G->edge[v1][v2]=weight;//无向边;邻接矩阵为对称矩阵
	G->edge[v2][v1]=weight;
	G->numOfEdges++;
	return 0;
}

//删除边<v1,v2>,v1,v2为顶点序号,成功返回0, 失败返回-1
int DeleteEdge(AdjMGraph*G,int v1,int v2){

	if(v1<0||v1>=G->Vertices.length||v2<0||v2>=G->Vertices.length||v1==v2){
		printf("parameter v1 or parameter v2 is illegal!",v1,v2);
		return -1;
	}
	if(G->edge[v1][v2]==MaxWeight||v1==v2){
		printf("The edge is not exist!");
		return -1 ;
	}
	G->edge[v1][v2]=MaxWeight;
	G->edge[v2][v1]=MaxWeight;
	G->numOfEdges--;
	return 0;
}
//取第一个邻接顶点序号,没有则返回-1
int GetFirstVex(AdjMGraph G,int v){
	int col;
	if(v<0||v>=G.Vertices.length){
		printf("parameter v is illegal!");
			return -1;
	}
	for(col=0;col<G.Vertices.length;col++){
		if(G.edge[v][col]>以上是关于图的各类算法实现的主要内容,如果未能解决你的问题,请参考以下文章

图类算法总结

在SIMULINK实现各类优化类算法的仿真——粒子群算法细菌觅食

java代码实现Dijkstra算法求图的最短路径

计算图的最短距离--Dijkstra算法

C++ 实现无向图的最小生成树Prim算法(附完整代码)

C++ 实现无向图的最小生成树Kruskal算法(完整代码)