邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
matrix.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h> #include "aqueue.h" #define MAX_VALUE INT_MAX
#define MAX_NUM 100 typedef char node_type; typedef struct matrix
{
node_type vertex[MAX_NUM];//节点信息
int arcs[MAX_NUM][MAX_NUM];//矩阵
int vertexs, brim;//节点数,边数
} Graph; void g_create(Graph * graph)
{
int num;
int i, j, k;
char c; printf("输入节点个数:");
scanf("%d", &graph->vertexs);
getchar();//接受回车键 printf("输入节点信息:");
for ( i = ; i < graph->vertexs; i++ )
{
scanf("%c", &graph->vertex[i]);
getchar();
} for ( i = ; i < graph->vertexs; i++ )//初始化矩阵
for ( j = ; j < graph->vertexs; j++ )
graph->arcs[i][j] = MAX_VALUE;
graph->brim = ;//初始化边数 // i 代表行数, j 是用来循环的, k 代表列数
for ( i = ; i < graph->vertexs; i++ )
{
printf("输入与%c节点相邻的节点与权值,输入#号键结束\n", graph->vertex[i]);
for ( j = ; j < graph->vertexs; j++ )
{
scanf("%c", &c);
if ( c == '#' )
{
getchar();
break;
}
scanf("%d", &num);
for ( k = ; k < graph->vertexs; k++ )
{
if ( graph->vertex[k] != c )
continue;
graph->arcs[i][k] = num;
graph->brim++;
}
getchar();
}
}
graph->brim /= ;
} void g_printMatrix(Graph * graph)//打印矩阵状态
{
int i, j; printf("brim = %d\n", graph->brim);
for ( i = ; i < graph->vertexs; i++ )
{
for ( j = ; j < graph->vertexs; j++ )
{
printf("%-10d ", graph->arcs[i][j]);
}
printf("\n");
}
} //深度优先遍历
static void dfs_graph(Graph * graph, bool visited[], const int i);
void g_depth_first_search(Graph * graph)
{
bool visited[graph->vertexs];
int i;
for ( i = ; i < graph->vertexs; i++ )
visited[i] = false;
visited[] = true;
dfs_graph(graph, visited, );
printf("\n");
} static void dfs_graph(Graph * graph, bool visited[], const int i)
{
int j;
printf("%c\t", graph->vertex[i]);
for ( j = ; j < graph->vertexs; j++ )//依次检查矩阵
{
if ( graph->arcs[i][j] != MAX_VALUE && !visited[j] )//i 代表矩阵的行, j 代表矩阵的列
{
visited[j] = true;
dfs_graph(graph, visited, j);
}
}
} //广度优先遍历
void g_breadth_first_search(Graph * graph)
{
Queue queue;//队列存储的是节点数组的下标(int)
bool visited[graph->vertexs];
int i, pos; q_init(&queue);
for ( i = ; i < graph->vertexs; i++ )
visited[i] = false; visited[] = true;
q_push(&queue, );
while ( !q_empty(&queue) )
{
pos = q_front(&queue);
printf("%c\t", graph->vertex[pos]);
for ( i = ; i < graph->vertexs; i++ )//把队头元素的邻接点入队
{
if ( !visited[i] && graph->arcs[pos][i] != MAX_VALUE )
{
visited[i] = true;
q_push(&queue, i);
}
}
q_pop(&queue);
}
printf("\n");
} //最小生成树prim算法
static void init_prim(Graph * graph, Graph * prim_tree);
void Prim(Graph * graph, Graph * prim_tree)
{
bool visited[graph->vertexs];
int i, j, k, h;
int power, power_j, power_k; for ( i = ; i < graph->vertexs; i++ )
visited[i] = false;
init_prim(graph, prim_tree); visited[] = true;
for ( i = ; i < graph->vertexs; i++ )
{
power = MAX_VALUE;
for ( j = ; j < graph->vertexs; j++ )
{
if ( visited[j] )
{
for ( k = ; k < graph->vertexs; k++ )
{
if ( power > graph->arcs[j][k] && !visited[k] )
{
power = graph->arcs[j][k];
power_j = j;
power_k = k;
}
}
}
}
//min power
if ( !visited[power_k] )
{
visited[power_k] = true;
prim_tree->arcs[power_j][power_k] = power;
}
}
} static void init_prim(Graph * graph, Graph * prim_tree)
{
int i, j; prim_tree->vertexs = graph->vertexs;
for ( i = ; i < prim_tree->vertexs; i++ )//初始化节点
prim_tree->vertex[i] = graph->vertex[i];
for ( i = ; i < prim_tree->vertexs; i++ )//初始化矩阵
{
for ( j = ; j < prim_tree->vertexs; j++ )
{
prim_tree->arcs[i][j] = MAX_VALUE;
}
}
} //最小生成树kruskal算法
typedef struct
{
int head;//边的始点下标
int tail;//边的终点下标
int power;//边的权值
} Edge; static void init_kruskal(Graph * graph, Graph * kruskal_tree);
static void my_sort(Edge * arr, int size);
void kruskal(Graph * graph, Graph * kruskal_tree)
{
int visited[graph->vertexs];
Edge edge[graph->brim];
int i, j, k;
int v1, v2, vs1, vs2; for ( i = ; i < graph->vertexs; i++ )
visited[i] = i; k = ;
for ( i = ; i < graph->vertexs; i++ )
{
for ( j = i + ; j < graph->vertexs; j++ )
{
if ( graph->arcs[i][j] != MAX_VALUE )
{
edge[k].head = i;
edge[k].tail = j;
edge[k].power = graph->arcs[i][j];
k++;
}
}
} init_kruskal(graph, kruskal_tree);
my_sort(edge, graph->brim); for ( i = ; i < graph->brim; i++ )
{
v1 = edge[i].head;
v2 = edge[i].tail;
vs1 = visited[v1];
vs2 = visited[v2];
if ( vs1 != vs2 )
{
kruskal_tree->arcs[v1][v2] = graph->arcs[v1][v2];
for ( j = ; j < graph->vertexs; j++ )
{
if ( visited[j] == vs2 )
visited[j] = vs1;
}
}
}
} static void init_kruskal(Graph * graph, Graph * kruskal_tree)
{
int i, j; kruskal_tree->vertexs = graph->vertexs;
kruskal_tree->brim = graph->brim; for ( i = ; i < graph->vertexs; i++ )
kruskal_tree->vertex[i] = graph->vertex[i]; for ( i = ; i < graph->vertexs; i++ )
for ( j = ; j < graph->vertexs; j++ )
kruskal_tree->arcs[i][j] = MAX_VALUE;
} static void my_sort(Edge * arr, int size)
{
int i, j;
Edge tmp; for ( i = ; i < size - ; i++ )
{
for ( j = i + ; j < size; j++ )
{
if ( arr[i].power > arr[j].power )
{
tmp.head = arr[i].head;
tmp.tail = arr[i].tail;
tmp.power = arr[i].power; arr[i].head = arr[j].head;
arr[i].tail = arr[j].tail;
arr[i].power = arr[j].power; arr[j].head = tmp.head;
arr[j].tail = tmp.tail;
arr[j].power = tmp.power;
}
}
}
} int main(void)
{
Graph graph;
Graph prim_tree;
Graph kruskal_tree; g_create(&graph);
g_printMatrix(&graph);
// printf("\n");
// g_depth_first_search(&graph);
// g_breadth_first_search(&graph);
//
// Prim(&graph, &prim_tree);
// g_printMatrix(&prim_tree);
// g_depth_first_search(&prim_tree);
// g_breadth_first_search(&prim_tree); kruskal(&graph, &kruskal_tree);
g_printMatrix(&kruskal_tree); return ;
}
aqueue.h
#ifndef _QUEUE_H
#define _QUEUE_H #define MAXSIZE 10 typedef struct queue
{
int * arr;
int front;
int rear;
} Queue; void q_init(Queue * queue);//初始化
void q_push(Queue * queue, const int data);//入队
void q_pop(Queue * queue);//出队
bool q_empty(Queue * queue);//为空
bool q_full(Queue * queue);//为满
int q_size(Queue * queue);//队大小
int q_front(Queue * queue);//队头元素
int q_back(Queue * queue);//队尾元素
void q_destroy(Queue * queue);//销毁 #endif //_QUEUE_h
aqueue.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h> #include "aqueue.h" void q_init(Queue * queue)
{
queue->arr = (int *)malloc( sizeof(int) * MAXSIZE );//初始化数组
assert(queue->arr != NULL);
queue->front = ;
queue->rear = ;
} void q_push(Queue * queue, const int data)
{
if ( q_full(queue) )
return;
queue->arr[queue->rear++] = data;//入队,队尾+1
queue->rear = queue->rear % MAXSIZE;//如果队尾
} void q_pop(Queue * queue)
{
if ( q_empty(queue) )
return;
queue->front = ++queue->front % MAXSIZE;//front+1,对MAXSIZE取余
} bool q_empty(Queue * queue)
{
return queue->front == queue->rear;
} bool q_full(Queue * queue)
{
return queue->front == (queue->rear + ) % MAXSIZE;
} int q_size(Queue * queue)
{
return (queue->rear - queue->front) % MAXSIZE;
} int q_front(Queue * queue)
{
assert( !q_empty(queue) );
return queue->arr[queue->front];
} int q_back(Queue * queue)
{
assert( !q_empty(queue) );
return queue->arr[queue->rear - ];
} void q_destroy(Queue * queue)
{
free(queue->arr);
}
邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)的更多相关文章
- 邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
graph.c #include <stdio.h> #include <stdlib.h> #include <limits.h> #include " ...
- 存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现
如果看完本篇博客任有不明白的地方,可以去看一下<大话数据结构>的7.4以及7.5,讲得比较易懂,不过是用C实现 下面内容来自segmentfault 存储结构 要存储一个图,我们知道图既有 ...
- 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件
老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...
- 图的理解:深度优先和广度优先遍历及其 Java 实现
遍历 图的遍历,所谓遍历,即是对结点的访问.一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略: 深度优先遍历 广度优先遍历 深度优先 深度优先遍历,从初始访问结点出发,我们知道 ...
- [源码解析] PyTorch 如何实现后向传播 (4)---- 具体算法
[源码解析] PyTorch 如何实现后向传播 (4)---- 具体算法 目录 [源码解析] PyTorch 如何实现后向传播 (4)---- 具体算法 0x00 摘要 0x01 工作线程主体 1.1 ...
- 图的深度优先和广度优先遍历(图以邻接表表示,由C++面向对象实现)
学习了图的深度优先和广度优先遍历,发现不管是教材还是网上,大都为C语言函数式实现,为了加深理解,我以C++面向对象的方式把图的深度优先和广度优先遍历重写了一遍. 废话不多说,直接上代码: #inclu ...
- JavaScript实现树深度优先和广度优先遍历搜索
1.前置条件 我们提前构建一棵树,类型为 Tree ,其节点类型为 Note.这里我们不进行过多的实现,简单描述下 Note 的结构: class Node{ constructor(data){ t ...
- 图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)
主要参考资料:数据结构(C语言版)严蔚敏 ,http://blog.chinaunix.net/uid-25324849-id-2182922.html 代码测试通过. package 图的建 ...
- lodash源码分析之compact中的遍历
小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅 ...
随机推荐
- js 判断微信浏览器
上周接到个需求,需求是这样的:用户扫一扫二维码会产生一个链接,该链接会向后端发送个请求,返回一个 apk 的下载地址,用户点击下载按钮可以下载此 apk.然后就发生了问题,经过测试,发现用微信扫一扫打 ...
- EPLAN部件库之共享方法
在使用EPLAN时经常会碰到自己电脑里的部件库和公司里其他同事的部件库存在差异,如果不是很平凡的同步所有使用的部件库,这种现象是不可避免的.这种情况对于一个团队用户来说是很麻烦的已经事,给维护部件库也 ...
- Hashing Trick
本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 在机器学习领域, kernel trick是一种非常有效的比较两个样本(对象)的方法. 给定两 ...
- .htaccess 语法以及应用
[转] http://blog.sina.com.cn/s/blog_6e8b46e701014drc.html http://blog.sina.com.cn/s/blog_6e8b46e70101 ...
- easyui datagrid to excel
$.extend($.fn.datagrid.methods, { toExcel: function(jq, filename){ return jq.each(function(){ var ur ...
- Web API 入门系列- 从一个示例开始
1.新建Web API项目 2.新建bookModel 3.新建book web api 控制器 为了简单方便,演示系统使用内存集合持久化书籍. 4.测试web api 我们怎么方便测试web api ...
- zk框架销毁Page上的Component
销毁Page上的Component ZK的组件之间是树状结构的,每一组件都只有一个根. 从页面上销毁一个组件可以通过下面两种方式来实现: 1. 组件不是根组件时:Component.setParent ...
- MyBatis知多少(12)私有数据库
如果你从事软件开发工作有了一段时间的话,那么肯定听过关于“自己动手还是花钱购买” 的争论.该争论是说,针对一个业务问题,我们是应该自己动手构建自己的解决方案呢,还是应 该花钱购买一个声称已经解决了此问 ...
- 3D全景!这么牛!!
如果你用过网页版的百度地图,你大概3D全景图浏览是一种怎样的酷炫体验:在一个点可以360度环顾周围的建筑.景色,当然也可以四周移动,就像身临其境. 全景图共分为三种: ①球面全景图 利用一张全景图围成 ...
- 比较几种工具Python(x,y) Anaconda WinPython
浏览了一些相关的论坛,将几大工具的特点分别总结下: Python(x,y) 更新很慢,稳定性一般,默认带有很多包. WinPython 只能在windows上跑,界面友好,和Python(x,y)是 ...