期末复习(3)C语言数据结构_图论基础

目录

导言:

 定义:

一、边和度的概念:

1.1 无向图中的边和度:

1.2 有向图中的边和度:

1.3 度序列和握手定理:

二、弧和度的关系:

2.1 有向图中的弧和度:

2.2 度序列和握手定理在有向图中的应用:

2.3 邻接矩阵和邻接表在有向图中的表示:

2.4 强连通图:

三、完全图:

3.1 完全图的定义:

3.2 完全图的度:

3.3 完全图的表示和操作:

四、连通图:

4.1 连通图的定义:

无向连通图: 如果一个无向图是连通的,那么它就是无向连通图。也就是说,任意两个顶点之间都存在一条无向路径。

有向连通图: 如果一个有向图是连通的,那么它就是有向连通图。对于任意两个顶点,存在一条有向路径从一个顶点到达另一个顶点。

4.2 连通图的表示和操作:

DFS判断连通性: 使用深度优先搜索,从一个起始顶点开始,递归地访问与之相邻的未访问过的顶点,标记已访问的顶点。如果所有顶点都能被访问到,那么图是连通的。

 BFS判断连通性: 使用广度优先搜索,从一个起始顶点开始,逐层访问与之相邻的未访问过的顶点,标记已访问的顶点。如果所有顶点都能被访问到,那么图是连通的。

导言:

        图论作为离散数学的一部分,是计算机科学中重要的基础理论之一。在C语言数据结构中,图的表示和应用也是一个关键领域。本文将介绍图论的基础概念,包括边、度、弧、以及两个重要类型的图——完全图和连通图,并结合C语言数据结构进行应用。

 定义:

        图 (Graph) 是一种复杂的非线性数据结构,   由顶点集合及顶点间的关系(也称弧或边)集合   组成。可以表示为: G=(V, VR)   其中 V 是顶点的有穷非空集合; VR 是顶点之间关系的有穷集合,也叫做弧或边集合。弧是顶点   的有序对,边是顶点的无序对。 

一、边和度的概念:

        在图论中,边是连接图中两个顶点的关系,它是图中最基本的元素之一。边可以是有向的或无向的,这决定了连接两个顶点的方向性。图的边可以用来表示不同实体之间的关系,例如在社交网络中,顶点可以代表个人,边则表示两个个人之间的关系。

1.1 无向图中的边和度:

        在无向图中,边没有方向。如果图中有一条连接顶点A和顶点B的边,那么同样存在一条连接顶点B和顶点A的边。一个顶点的度是指与之相邻的边的数量。在无向图中,顶点的度等于与之相连的边的数量。

1.2 有向图中的边和度:

        有向图中的边有方向,从一个顶点指向另一个顶点。每条边都有一个始点和一个终点。一个顶点的出度是从该顶点出发的边的数量,入度是指向该顶点的边的数量。一个顶点的度等于其出度和入度之和。

        在C语言中,可以使用邻接矩阵或邻接表表示图的边和度信息。邻接矩阵是一个二维数组,其中元素a[i][j]表示顶点i和顶点j之间是否有边;邻接表则是一个链表数组,每个顶点对应一个链表,链表中存储与该顶点相邻的顶点。

1.3 度序列和握手定理:

        度序列是一个图中所有顶点度数的序列。握手定理指出,对于任意一个图,其所有顶点的度数之和等于边数的两倍。即,对于一个无向图,2×边数=所有顶点的度数之和2×边数=所有顶点的度数之和;对于一个有向图,2×边数=所有顶点的度数之和2×边数=所有顶点的度数之和。

二、弧和度的关系:

        在有向图中,边被称为弧,它有方向性,表示从一个顶点指向另一个顶点的箭头。与边相似,弧也带有度的概念,分为入度和出度。以下是更详细的讨论:

2.1 有向图中的弧和度:

        考虑一个有向图,其中有三个顶点A、B和C,它们之间有以下有向弧:

  • 有向弧A → B,表示从A指向B的方向
  • 有向弧B → C,表示从B指向C的方向
  • 有向弧C → A,表示从C指向A的方向

        每个顶点的入度和出度如下:

  • 顶点A的入度为1,出度为1
  • 顶点B的入度为1,出度为1
  • 顶点C的入度为1,出度为1

        一个顶点的度等于其入度和出度之和。握手定理同样适用于有向图。

2.2 度序列和握手定理在有向图中的应用:

        度序列在有向图中的应用与无向图类似。考虑有向图的度序列1,1,11,1,1,它表示每个顶点的度数都是1。握手定理在这里也成立,因为2×边数=2×3=6=所有顶点的度数之和2×边数=2×3=6=所有顶点的度数之和。

2.3 邻接矩阵和邻接表在有向图中的表示:

        在C语言数据结构中,有向图可以使用邻接矩阵或邻接表来表示。邻接矩阵是一个二维数组,其中元素a[i][j]表示从顶点i到顶点j的有向弧的存在。邻接表是一个链表数组,每个顶点对应一个链表,链表中存储从该顶点出发的有向弧。

2.4 强连通图:

        在有向图中,如果任意两个顶点之间都存在双向路径(即A到B有路径,B到A也有路径),则该有向图是强连通图。强连通图中的任意两个顶点都可以通过有向路径互相到达。

三、完全图:

        完全图是图论中一个重要的概念,它是每一对不同的顶点都有一条边相连的图。在C语言数据结构中,我们可以通过邻接矩阵或邻接表来表示完全图,并对其进行相关操作。

3.1 完全图的定义:

        一个完全图具有以下特点:

  • 每一对不同的顶点之间都存在一条边。
  • 对于n个顶点的完全图,边的数量为n×(n-1)/2

3.2 完全图的度:

        考虑一个完全图,如果有n个顶点,每个顶点的度都是n-1,因为每个顶点都与其他所有顶点相连。

3.3 完全图的表示和操作:

        在C语言中,可以使用邻接矩阵或邻接表来表示完全图。

  • 邻接矩阵表示: 完全图的邻接矩阵是一个二维数组,其中元素a[i][j]表示顶点i和顶点j之间是否有边。对于完全图,矩阵的主对角线上的元素都是0,其他元素都是1。
int completeGraph[MAX][MAX];

// 初始化完全图的邻接矩阵
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        if (i == j) {
            completeGraph[i][j] = 0; // 主对角线上的元素为0
        } else {
            completeGraph[i][j] = 1; // 其他元素为1
        }
    }
}

邻接表表示: 完全图的邻接表中,每个顶点的链表都包含所有其他顶点。每个节点表示一个边。

struct Node {
    int vertex;
    struct Node* next;
};

struct Graph {
    struct Node* adjacencyList[MAX];
};

// 初始化完全图的邻接表
struct Graph completeGraph;

for (int i = 0; i < n; i++) {
    completeGraph.adjacencyList[i] = NULL;
    for (int j = 0; j < n; j++) {
        if (i != j) {
            // 添加边
            struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
            newNode->vertex = j;
            newNode->next = completeGraph.adjacencyList[i];
            completeGraph.adjacencyList[i] = newNode;
        }
    }
}

四、连通图:

        连通图是图论中另一个基本概念,它指的是图中任意两个顶点都能通过边的路径相连。在C语言数据结构中,我们可以通过深度优先搜索(DFS)和广度优先搜索(BFS)等算法来判断图的连通性,寻找路径等。

4.1 连通图的定义:

        一个图被称为连通图,如果对于图中的任意两个不同的顶点,存在一条路径使它们相连。连通图分为无向连通图和有向连通图两种情况。

  • 无向连通图: 如果一个无向图是连通的,那么它就是无向连通图。也就是说,任意两个顶点之间都存在一条无向路径。
  • 有向连通图: 如果一个有向图是连通的,那么它就是有向连通图。对于任意两个顶点,存在一条有向路径从一个顶点到达另一个顶点。

4.2 连通图的表示和操作:

        在C语言中,我们可以使用邻接矩阵或邻接表来表示图,并通过深度优先搜索(DFS)或广度优先搜索(BFS)等算法来判断图的连通性。

        DFS判断连通性: 使用深度优先搜索,从一个起始顶点开始,递归地访问与之相邻的未访问过的顶点,标记已访问的顶点。如果所有顶点都能被访问到,那么图是连通的。
void DFS(int vertex, int visited[], struct Graph* graph) {
    visited[vertex] = 1; // 标记当前顶点为已访问

    // 访问与当前顶点相邻的未访问过的顶点
    struct Node* current = graph->adjacencyList[vertex];
    while (current != NULL) {
        if (!visited[current->vertex]) {
            DFS(current->vertex, visited, graph);
        }
        current = current->next;
    }
}
         BFS判断连通性: 使用广度优先搜索,从一个起始顶点开始,逐层访问与之相邻的未访问过的顶点,标记已访问的顶点。如果所有顶点都能被访问到,那么图是连通的。
void BFS(int start, int visited[], struct Graph* graph) {
    // 使用队列实现广度优先搜索
    int queue[MAX];
    int front = 0, rear = 0;

    visited[start] = 1;
    queue[rear++] = start;

    while (front < rear) {
        int currentVertex = queue[front++];
        struct Node* current = graph->adjacencyList[currentVertex];

        while (current != NULL) {
            if (!visited[current->vertex]) {
                visited[current->vertex] = 1;
                queue[rear++] = current->vertex;
            }
            current = current->next;
        }
    }
}

        连通图中任意两个顶点都能通过边的路径相连。使用深度优先搜索(DFS)和广度优先搜索(BFS)等算法,我们可以判断图的连通性和找到路径。这在网络设计、路径规划等领域具有实际应用。

  • 34
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值