邻接矩阵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 = 0; i < graph->vertexs; i++ )
    {
        scanf("%c", &graph->vertex[i]);
        getchar();
    }

    for ( i = 0; i < graph->vertexs; i++ )//初始化矩阵
        for ( j = 0; j < graph->vertexs; j++ )
            graph->arcs[i][j] = MAX_VALUE;
    graph->brim = 0;//初始化边数

    // i 代表行数, j 是用来循环的, k 代表列数
    for ( i = 0; i < graph->vertexs; i++ )
    {
        printf("输入与%c节点相邻的节点与权值,输入#号键结束\n", graph->vertex[i]);
        for ( j = 0; j < graph->vertexs; j++ )
        {
            scanf("%c", &c);
            if ( c == ‘#‘ )
            {
                getchar();
                break;
            }
            scanf("%d", &num);
            for ( k = 0; k < graph->vertexs; k++ )
            {
                if ( graph->vertex[k] != c )
                    continue;
                graph->arcs[i][k] = num;
                graph->brim++;
            }
            getchar();
        }
    }
    graph->brim /= 2;
}

void g_printMatrix(Graph * graph)//打印矩阵状态
{
    int i, j;

    printf("brim = %d\n", graph->brim);
    for ( i = 0; i < graph->vertexs; i++ )
    {
        for ( j = 0; 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 = 0; i < graph->vertexs; i++ )
        visited[i] = false;
    visited[0] = true;
    dfs_graph(graph, visited, 0);
    printf("\n");
}

static void dfs_graph(Graph * graph, bool visited[], const int i)
{
    int j;
    printf("%c\t", graph->vertex[i]);
    for ( j = 0; 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 = 0; i < graph->vertexs; i++ )
        visited[i] = false;

    visited[0] = true;
    q_push(&queue, 0);
    while ( !q_empty(&queue) )
    {
        pos = q_front(&queue);
        printf("%c\t", graph->vertex[pos]);
        for ( i = 0; 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 = 0; i < graph->vertexs; i++ )
        visited[i] = false;
    init_prim(graph, prim_tree);

    visited[0] = true;
    for ( i = 0; i < graph->vertexs; i++ )
    {
        power = MAX_VALUE;
        for ( j = 0; j < graph->vertexs; j++ )
        {
            if ( visited[j] )
            {
                for ( k = 0; 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 = 0; i < prim_tree->vertexs; i++ )//初始化节点
        prim_tree->vertex[i] = graph->vertex[i];
    for ( i = 0 ; i < prim_tree->vertexs; i++ )//初始化矩阵
    {
        for ( j = 0; 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 = 0; i < graph->vertexs; i++ )
        visited[i] = i;

    k = 0;
    for ( i = 0; i < graph->vertexs; i++ )
    {
        for ( j = i + 1; 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 = 0; 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 = 0; 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 = 0; i < graph->vertexs; i++ )
        kruskal_tree->vertex[i] = graph->vertex[i];

    for ( i = 0; i < graph->vertexs; i++ )
        for ( j = 0; 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 = 0; i < size - 1; i++ )
    {
        for ( j = i + 1; 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 0;
}

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 = 0;
    queue->rear = 0;
}

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 + 1) % 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 - 1];
}

void q_destroy(Queue * queue)
{
    free(queue->arr);
}
时间: 02-18

邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)的相关文章

邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

graph.c #include <stdio.h> #include <stdlib.h> #include <limits.h> #include "aqueue.h" #define MAX_NUM 100 typedef char node_type; typedef struct arc_node { int pos; int distance; struct arc_node * next; } Arc_node;//保存Node节点的相

存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现

如果看完本篇博客任有不明白的地方,可以去看一下<大话数据结构>的7.4以及7.5,讲得比较易懂,不过是用C实现 下面内容来自segmentfault 存储结构 要存储一个图,我们知道图既有结点,又有边,对于有权图来说,每条边上还带有权值.常用的图的存储结构主要有以下二种: 邻接矩阵 邻接表 邻接矩阵 我们知道,要表示结点,我们可以用一个一维数组来表示,然而对于结点和结点之间的关系,则无法简单地用一维数组来表示了,我们可以用二维数组来表示,也就是一个矩阵形式的表示方法. 我们假设A是这个二维数组

数据结构之深度优先,广度优先遍历

深度优先和广度优先遍历在树和图中应用最为普遍,思想也类似,因此放到一起来总结. 二叉树的深度优先广度优先遍历: 一棵二叉树(2,(2(3,4),3(4,5))),这是一棵满二叉树,一共有7个节点,根节点2,深度为3 数据结构定义如下: class Node: def __init__(self, value=None, left = None, right = None): self.value = value self.left = left self.right = right 先根遍历 d

树的深度优先与广度优先遍历

简述树的深度优先及广度优先遍历算法,并说明非递归实现. 原题出自百度的笔试: 当时我看到这个题目的时候,已经完全记不得非递归算法该怎么实现了,后来查阅了一下,要用到两个辅助的数据结构: 深度优先遍历--->栈: 广度优先遍历--->队列: 这里以二叉树为例来实现. import java.util.ArrayDeque; public class BinaryTree { static class TreeNode{ int value; TreeNode left; TreeNode rig

Apache Spark源码走读之21 -- 浅谈mllib中线性回归的算法实现

欢迎转载,转载请注明出处,徽沪一郎. 概要 本文简要描述线性回归算法在Spark MLLib中的具体实现,涉及线性回归算法本身及线性回归并行处理的理论基础,然后对代码实现部分进行走读. 线性回归模型 机器学习算法是的主要目的是找到最能够对数据做出合理解释的模型,这个模型是假设函数,一步步的推导基本遵循这样的思路 假设函数 为了找到最好的假设函数,需要找到合理的评估标准,一般来说使用损失函数来做为评估标准 根据损失函数推出目标函数 现在问题转换成为如何找到目标函数的最优解,也就是目标函数的最优化

【深度】扒开V8引擎的源码,我找到了你们想要的前端算法(下次面试官再问算法,用它怼回去!)

算法对于前端工程师来说总有一层神秘色彩,这篇文章通过解读V8源码,带你探索`Array.prototype.sort`函数下的算法实现. 来,先把你用过的和听说过的排序算法都列出来: * 快速排序 * 冒泡排序 * 插入排序 * 归并排序 * 堆排序 * 希尔排序 * 选择排序 * 计数排序 * 桶排序 * 基数排序 * ... 答题环节到了, sort 函数使用的以上哪一种算法? 如果你在网上搜索过关于 sort 源码的文章,可能会告诉你数组长度小于10用插入排序,否则用快速排序. 开始我也是

lodash源码分析之compact中的遍历

小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅浅的海峡, 我在这头, 大陆在那头. --余光中<乡愁> 本文为读 lodash 源码的第三篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 作用与用法 compact 函数用来去除数组中的

图的邻接表+深度优先遍历+广度优先遍历

1 /** 2 无向图的邻接表存储 3 深度优先遍历递归 4 广度优先遍历递归+非递归 5 */ 6 #include <stdio.h> 7 #include <string.h> 8 #include <malloc.h> 9 #define N 5 10 #define MAX 50 11 typedef struct A{ 12 int adjvex; 13 struct A* nextArc; 14 }Arc; 15 typedef struct node{

二叉树的深度优先和广度优先遍历

深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止. 二叉树的深度优先遍历和先序遍历结果一样的. 思想是采用栈, 首先将根结点压入栈,如果栈不为空,而后出栈并输出当前结点中值,而后先把右子树