【趣学C语言和数据结构100例】81-85

简介: 本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。

【趣学C语言和数据结构100例】

问题描述

81.BFS算法求解单源最短路径问题(权值相同也适用)

82.已知一个有向图使用邻接矩阵存储,写出一个算法求图中入度为0的点的个数。

(扩展)已知一个有向图使用邻接矩阵存储,写出一个算法求图中出度为0的点的个数。

83.设计一个算法,统计一个采用邻接表存储的具有n个顶点的无向无权图所有顶点的度

84.折半查找

85.二叉排序树的查找

代码分析

==81.BFS最短路径==
分析:传入图的结构体,u: 表示起始顶点(源点),d[]: 一个整数数组,用于存储从源点 u 到每个顶点的最短距离。visited[]: 一个布尔数组,用于标记每个顶点是否已被访问。先遍历所有的点标计最短距离为-1,每个顶点为已被访问0.创建队列,初始化队列,u 入队,使用广度优先搜索,循环持续进行,直到队列为空。每次循环从队列中取出一个顶点 u,然后遍历其所有未访问的邻接顶点 w。对于每个未访问的邻接顶点 w,将其距离设置为 d[u] + 1(因为边权为1),将其加入队列,并标记为已访问。

==82.有向图邻接矩阵,入度为0的点,出度为0的点==

//邻接矩阵的数据结构
typedef struct {
   
    int edge[Max_num][Max_num]; // 邻接矩阵
    int vexnum; // 图的顶点数
    int edgenum; // 图的边数
} AMGraph;

分析:在邻接矩阵 行为出度,列为入度,传入图G,故函数名为void 函数名(AMGraph G).使用for循环遍历,条件为<图的点。对于每个顶点 i,使用 tag 变量标记其入度是否为 0。初始值为 0,表示入度为 0。内层循环遍历所有其他顶点 j (从 0 到 G.vexnum - 1),检查 G.edge[j][i] 是否不为 0。G.edge[j][i] 表示从顶点 j 到顶点 i 是否存在边。如果存在边 (不为 0),则将 tag 设置为 1,表示入度不为 0,并跳出内层循环。如果内层循环结束后 tag 仍然为 0,则表示顶点 i 的入度为 0,count 计数器加 1。函数返回 count,即入度为 0 的顶点数。

==83.有向图邻接表所有顶点的度==
分析:这段代码的核心思想是遍历每个顶点的邻接表,统计邻接表中节点的数量,即该顶点的度。node_degree(ALGraph G) 函数接受一个邻接表表示的图 G 作为输入。外层循环 for(int i=0; i < G.vexnum; i++) 遍历图中的每个顶点。G.vexnum 表示图中顶点的数量。内层循环 while (p ) 遍历当前顶点 i 的邻接表。p 指向邻接表中的弧节点,p->nextarc 指向下一个弧节点。count 变量累加邻接表中节点的数量,最终表示该顶点的度。printf 函数打印每个顶点的度。

==84.折半查找==
分析:传入数组,数组的大小,要查找的k,定义左low右high,如果lowk,就使low=mid+1。到结束如果为找到,返回-1.

==85.二叉排序树的查找==

//二叉树的数据结构
typedef struct Bstnode {
   
    int data;
    int Bstnode *lchild, *rchild;
} Bstnode, *Bstree;

分析:传入树和要找到的值,故函数名为Bstnode* func(Bstree T,int key),如果树此时的值不为要找的,那么使用while循环一直,如果key<值,则使T为左子树,否则去右字树。最后返回找到的T 。

代码实现

#include<stdio.h>
int mian(){
   
//    81.BFS算法求解单源最短路径问题(权值相同也适用)
void BFS_min(Groph G,int u,int d[],bool visited[]){
   
    for(int i=0;i<G.vex.num;i++){
   
        d[i]=-1;
        visited[i]=false;
    }
    d[u]=0;
    visited[u]=true;
    Queue Q;    //创建 队列
    InitQueue(&Q);    // 初始化队列
    EnQueue(Q,u);    //u入对 
    while(!IsEmpty(Q)){
   
        DeQueue(Q,u);
        for(int w=FirstNeighbor(Q,u);w>=0;w--){
   
            w=NextNeighbor(Q,u,w);
            if(visited[w]==false){
   
                d[w]=d[u]+1;
                EnQueue(Q,w);
                visited[w]=true;
            }
        }
    }
}

//    82.已知一个有向图使用邻接矩阵存储,写出一个算法求图中入度为0的点的个数。
//    邻接矩阵 行为出度,列为入度 
typedef struct {
   
    int edge[Max_num][Max_num]; // 邻接矩阵
    int vexnum; // 图的顶点数
    int edgenum; // 图的边数
} AMGraph;
int sum_zero(AMGraph G){
   
    int count=0,tag;
    for(int i=0;i<G.vexnum;i++){
   
        tag=0;
        for(int j=0;j<G.vexnum;j++){
   
            if(G.edge[j][i]!=0){
   
                tag=1;
                break;
            }
        }
        if(tag==0){
   
            count++;
        }
    }
    return count;
}    
//(扩展)已知一个有向图使用邻接矩阵存储,写出一个算法求图中出度为0的点的个数。
int sum_zero(AMGraph G){
   
    int count=0,tag;
    for(int i=0;i<G.vexnum;i++){
   
        tag=0;
        for(int j=0;j<G.vexnum;j++){
   
            if(G.edge[i][j]!=0){
   
                tag=1;
                break;
            }
        }
        if(tag==0){
   
            count++;
        }
    }
    return count;
}

//    83.设计一个算法,统计一个采用邻接表存储的具有n个顶点的无向无权图所有顶点的度    
void node_degree(ALGraph G){
   
    ArcNode *p;
    for(int i=0;i<G.vexnum;i++){
   
        int count=0;
        p=G.vertices[v].firstarc;
        while(p){
   
            count++;
            p=p->nextarc;
        }
        printf("结点%d的度为%d",i,count);
    }
}

//    84.折半查找
int func(int l[],int n,int k){
   
    int low=0,high=n-1,mid;
    while(low<high){
   
        min=(low+high)/2;
        if(l[mid]==k){
   
            return min;
        }
        else if(l[mid]<k){
   
            high=mid-1;
        }else{
   
            low=mid+1;
        }
    }
    return -1;
}

//    85.二叉排序树的查找
typedef struct Bstnode {
   
    int data;
    int Bstnode *lchild, *rchild;
} Bstnode, *Bstree;
Bstnode* func(Bstree T,int key){
   
    while(T && T->dada!=key){
   
        if(key<T->dada){
   
            T=T->lchild;
        }else{
   
            T=T->rchild;
        }    
    }
    return T;
}


}

    return 0;
}

总结

本文探讨了五个经典的算法问题及其C语言实现,涵盖了图论和树结构的基本概念和操作。这些问题包括使用BFS算法求解单源最短路径问题、统计有向图中入度和出度为0的点的个数、统计无向无权图中所有顶点的度、折半查找和二叉排序树的查找。这些算法不仅在理论上具有重要意义,而且在实际应用中也非常广泛。

BFS算法求解单源最短路径问题是图论中的一个基础问题,通过广度优先搜索,我们可以找到从源点到其他所有顶点的最短路径。这种方法适用于权值相同的情况,通过队列实现,能够保证找到的路径是最短的。

统计有向图中入度和出度为0的点的个数的问题,涉及到对邻接矩阵的遍历和判断。这两个问题分别对应于图中没有入边和出边的顶点,对于图的分析和处理具有重要意义。

统计无向无权图中所有顶点的度的问题,通过遍历邻接表来实现。每个顶点的度即其邻接表中节点的数量,这个统计对于理解图的结构和特性非常有帮助。

折半查找是一种高效的查找算法,它通过二分数组来减少查找时间,适用于有序数组中的查找操作。折半查找的时间复杂度为O(log n),远高于顺序查找的O(n)。

二叉排序树的查找是树结构操作的一个基础问题。二叉排序树(BST)是一种特殊的二叉树,其中每个节点的值都大于其左子树中的任何值,且小于其右子树中的任何值。这种特性使得BST在查找、插入和删除操作上都非常高效。

这些算法的实现不仅展示了C语言在数据处理和结构操作方面的能力,也体现了算法设计的基本思想,如广度优先搜索、二分查找和树结构操作。通过这些算法的学习,我们可以更好地理解数据结构和算法的基本概念,提高解决实际问题的能力。

总的来说,这些算法问题不仅锻炼了编程能力,也加深了对算法和数据结构的理解。通过这些问题的解决,我们可以逐步提高自己的编程技能,为将来的学习和工作做好准备。这些算法的掌握对于计算机专业的学生和软件开发人员来说都是非常重要的。

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