图的各类算法实现
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]>以上是关于图的各类算法实现的主要内容,如果未能解决你的问题,请参考以下文章