c语言数据结构-图的操作

简介: c语言数据结构-图的操作

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)目录

图的概念(http://t.csdn.cn/CH4Bv)

图的顺序存储结构

数组(邻接矩阵)表示法

定义

无向图

有向图

网的邻接矩阵表示法

图的链式存储结构

邻接表表示法

定义:

无向图;

有向图:

小结:


图的概念(http://t.csdn.cn/CH4Bv

图的顺序存储结构

数组(邻接矩阵)表示法

定义

                                 

建立一个顶点表和一个邻接矩阵(表示各个顶点之间关系)。

设图A=(V,E)有n个顶点,则图的邻接矩阵是一个二维数组A.Edge[n][n],

/** 图的类型枚举 */
typedef enum {
    DG,     //有向图   0
    UDG,    //无向图   1
    DN,     //有向网   2
    UDN     //无向网   3
}GraphKind;
/** 图的邻接矩阵存储表示 */
typedef struct {
    char* verTexs[100];                     //顶点数组
    int arcs[100][100];                     //邻接矩阵(权数组)
    int verTexCount;                        //图的顶点数
    int arcCount;                           //图的边/弧数
    GraphKind kind;                         //图的类型
}MatrixGraph;

无向图

特点:

1 、无向图的邻接矩阵是 对称

2 、顶点i的度=第i行(列)中1的个数

完全图的领接矩阵中,对角元素为0,其余1

/** 使用邻接矩阵表示法创建无向图 */
int CreateUDG(MatrixGraph* G) 
{
    G->kind = UDG;      //设置当前创建图的类型为无向图
    printf("请输入无向图的顶点数:");
    scanf("%d", &G->verTexCount);
    printf("请输入边的数量:");
    scanf("%d", &G->arcCount);
    printf("依次输入顶点信息\n");
    for (int i = 0; i < G->verTexCount; i++)
    {
        G->verTexs[i] = (char *)malloc(sizeof(char) * 10);
        printf("顶点%d:", i + 1);
        scanf("%s", G->verTexs[i]);
    }
    //初始化邻接矩阵,所有边的权值设置为0
    for (int i = 0; i < G->verTexCount; i++)
    {
        for (int j = 0; j < G->verTexCount; j++)
        {
            G->arcs[i][j] = 0;
        }
    }
    printf("请输入顶点和邻接顶点信息,构建邻接矩阵\n");
    for (int i = 0; i < G->arcCount; i++)
    {
        char * vex1 = (char *)malloc(sizeof(char) * 10);
        char * vex2 = (char *)malloc(sizeof(char) * 10);
        printf("顶点:");
        scanf("%s", vex1);
        printf("邻接点:");
        scanf("%s", vex2);
        //分别获得两个顶点在顶点数组中的坐标
        int x = LocateVex(G, vex1);
        int y = LocateVex(G, vex2);
        if (x == -1 || y == -1) 
        {
            return 0;
        }
        G->arcs[x][y] = 1;
        G->arcs[y][x] = G->arcs[x][y];      //无向图的邻接矩阵是对称的
        free(vex1);
        free(vex2);
    }
    return 1;
}

有向图

特点:

1 、 有向图的邻接矩阵 可能是不对称

2 、 顶点的 出度=第i行元素之和

       顶点的 入度=第i 列元素之和

       顶点的= 第i 行元素之和+ 第i列元素之和

/** 使用邻接矩阵表示法创建有向图 */
int CreateDG(MatrixGraph* G) {
    G->kind = DG;      //设置当前创建图的类型为有向图
    printf("请输入有向图的顶点数:");
    scanf("%d", &G->verTexCount);
    printf("请输入边的数量:");
    scanf("%d", &G->arcCount);
    printf("依次输入顶点信息\n");
    for (int i = 0; i < G->verTexCount; i++) {
        G->verTexs[i] = (char *)malloc(sizeof(char) * 10);
        printf("顶点%d:", i + 1);
        scanf("%s", G->verTexs[i]);
    }
    //初始化邻接矩阵,所有边的权值设置为0
    for (int i = 0; i < G->verTexCount; i++) {
        for (int j = 0; j < G->verTexCount; j++) {
            G->arcs[i][j] = 0;
        }
    }
    printf("请输入顶点和邻接顶点信息,构建邻接矩阵\n");
    for (int i = 0; i < G->arcCount; i++) {
        char * vex1 = (char *)malloc(sizeof(char) * 10);
        char * vex2 = (char *)malloc(sizeof(char) * 10);
        printf("顶点:");
        scanf("%s", vex1);
        printf("邻接点:");
        scanf("%s", vex2);
        //分别获得两个顶点在顶点数组中的坐标
        int x = LocateVex(G, vex1);
        int y = LocateVex(G, vex2);
        if (x == -1 || y == -1) {
            return 0;
        }
        G->arcs[x][y] = 1;
        //G->arcs[y][x] = G->arcs[x][y];      //有向图的邻接矩阵有可能不对称
        free(vex1);
        free(vex2);
    }
    return 1;
}

网的邻接矩阵表示法

图的链式存储结构

邻接表表示法

定义:

指数组与链表相结合的储存方法

对每个顶点V𝑗 建立一个单链表,把与V 𝑗 有关联的边的信息链接起来,每个结点设为3个域

1 、每个单链表有一个 头结点 (设为 2个域)),存V𝒋 信息

2 、每个单链表的头结点另外用顺序存储结构存储

/** 图的类型枚举 */
typedef enum
{
    DG,     //有向图   0
    UDG,    //无向图   1
    DN,     //有向网   2
    UDN     //无向网   3
}GraphKind;
/** 边/弧的结点 */
typedef struct node {
    int adjVex;                     //该边指向这条边邻接点的下标
    struct node* nextEdge;         //指向下一条边结点的指针
    struct node* nextArc;          //指向下一个弧结点的指针
    int weight;                 //权重
}EdgeNode, ArcNode;
/** 顶点结点 */
typedef struct vexNode {
    char* vex;                 //顶点值
    EdgeNode* firstEdge;           //指向第一条边的指针
    ArcNode* firstArc;             //指向第一条弧的指针
}VNode, AdjList[100];
/** 邻接表实现的图结构 */
typedef struct adjGraph {
    AdjList vexes;                  //顶点数组
    int vexCount;                   //顶点数量
    int edgeCount;                  //图的边数
    int arcCount;                   //图的弧数
    GraphKind kind;                 //图的类型
}AdjListGraph;

无向图;

 

注意:邻接表不唯一,因为各个边结点的链入顺序是任意的

TD(V𝒋 ) = 单链表中链接的结点个数

/** 返回顶点vex在顶点数组中的下标,没有找到返回-1 */
int LocateVex_AdjList(AdjListGraph* G, char* vex) {
    int index = -1;
    for (int i = 0; i < G->vexCount; i++) {
        if (strcmp(vex, G->vexes[i].vex) == 0) {
            index = i;
            break;
        }
    }
    return index;
}
/** 采用邻接表表示法创建无向图 */
int CreateUDG_AdjList(AdjListGraph* G) {
    G->kind = UDG;
    printf("请输入顶点数量:");
    scanf("%d", &G->vexCount);
    printf("请输入边的数量:");
    scanf("%d", &G->edgeCount);
    printf("请依次输入顶点信息\n");
    for (int i = 0; i < G->vexCount; i++) {
        G->vexes[i].vex = (char*)malloc(sizeof(char) * 10);
        printf("顶点%d:", i + 1);
        scanf("%s", G->vexes[i].vex);
        //初始化邻接表,把边置空
        G->vexes[i].firstEdge = NULL;
    }
    printf("请输入顶点和邻接点信息,构建邻接表\n");
    for (int i = 0; i < G->edgeCount; i++) {
        char* vex1 = (char*)malloc(sizeof(char) * 10);
        char* vex2 = (char*)malloc(sizeof(char) * 10);
        printf("顶点:");
        scanf("%s", vex1);
        printf("邻接点:");
        scanf("%s", vex2);
        int x = LocateVex_AdjList(G, vex1);
        int y = LocateVex_AdjList(G, vex2);
        if (x == -1 || y == -1) {
            free(vex1);
            free(vex2);
            return 0;
        }
        EdgeNode* edgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));
        edgeNode->adjVex = x;
        edgeNode->nextEdge = G->vexes[y].firstEdge;
        edgeNode->weight = 0;
        G->vexes[y].firstEdge = edgeNode;
        edgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));
        edgeNode->adjVex = y;
        edgeNode->nextEdge = G->vexes[x].firstEdge;
        edgeNode->weight = 0;
        G->vexes[x].firstEdge = edgeNode;
        free(vex1);
        free(vex2);
    }
    return 1;
}

有向图:

TD(V𝒋 ) = OD(V𝒋 ) + ID(V𝒋 )

小结:

相关文章
|
2月前
|
机器学习/深度学习 算法 C语言
【趣学C语言和数据结构100例】11-15
本文介绍了五个C语言编程问题及其实现,包括矩阵对角线元素之和、有序数组插入、数组逆序、杨辉三角输出和魔方阵生成。每个问题不仅涉及基本的数组操作,还涵盖了算法设计的核心思想,如循环、条件判断和递归。通过解决这些问题,读者可以加深对C语言和数据结构的理解,提升编程技能。这些问题的解决过程展示了如何有效处理数组和矩阵,以及如何利用算法优化程序性能,为实际应用提供了宝贵的实践经验。
63 4
【趣学C语言和数据结构100例】11-15
|
2月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
51 1
|
2月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
56 4
|
2月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
49 4
|
2月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
53 4
|
2月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
54 4
|
2月前
|
存储 算法 vr&ar
【趣学C语言和数据结构100例】71-75
本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
45 4
|
2月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】66-70
本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
37 4
|
2月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】51-55
本文介绍了五个关于链表操作的C语言实现案例,包括删除单链表中的重复元素、从两个有序链表中查找公共元素、判断一个链表是否为另一链表的连续子序列、判断循环双链表是否对称及合并两个循环单链表。每个案例都详细解析了算法思路与实现方法,涵盖了链表操作的多种场景,旨在帮助读者深入理解链表数据结构的应用,提升算法设计与编程能力。
47 4
|
2月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】16-20
本文精选了五个C语言编程问题,涵盖数组操作、字符串处理等基础领域。包括查找二维数组中的鞍点、折半查找法、统计文章中字符数量、电文解密及字符串连接。每个问题都附有详细的代码实现与分析,旨在帮助读者理解算法逻辑,提升编程技巧。通过这些实践,不仅能锻炼编程能力,还能加深对数据结构和算法的理解,为未来的学习和工作打下坚实基础。
69 4