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

简介: 《趣学C语言和数据结构100例》精选5个典型问题:计算某日为当年第几天、约瑟夫环问题、学生成绩处理及单链表的头插法和尾插法。涵盖基础算法、数组、指针、结构体和链表,展示数据结构在实际问题中的应用。通过这些算法的学习,提升编程能力和对数据结构的理解。

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

问题描述

41.给出年、月、日,计算该日是该年的第几天解析:需要掌握函数:判断是否为闰年

42.(约瑟夫环问题)有 n 个人围成一圈,顺序排号。从第 1 个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子,问最后留下的是原来第几号的那位,用指针+数组实现。

43.有 10 个学生,每个学生的数据包括学号,姓名,3 门课的成绩,从键盘输入 10 个学生数据。要求输出 3 门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3 门课程成绩平均分数)。

44.采用头插法建立单链表,头插法常用于逆置

45.采用尾插法建立单链表

代码分析

==41.经典闰年==
分析:判断为该年的第几天——>则需要判断2月的天数,即判断是否为闰年。先输入年、月、日。创造数组存储月份。2月先默认28天(如果后续为闰年,则天数+1),先计算<该月的月天数所具有的天数。判断是否为闰年并且月份>=3时对天数进行++;然后输出总天数。
写一个判断闰年函数:

  • 该年份能被4整除,但不能被100整除,是闰年。
  • 该年份能被400整除,是闰年。

记忆:4和400可以,100不行

int leap(int year){
   
    return year%4==0 && year%100!=0 || year%400==0;
}

==42.约瑟夫环问题==
分析:使用数组存储数据。先输入n,创造一个n大小的数组。赋初值为i+1(从1开始计数)。创造一个remain用来计数剩余人数,定义一个访问指针。只要remain剩余人数>1,就一直进行游戏。游戏开始,令p指向数组。在创造一个循环while(p!=people+n)(只要不到数组的最后一位,就一直判断,即用来遍历数组)(注意:==p是一位一位的移动,到最后一位之后,使p指向数组的开头==)游戏正式开始,如果p此时指向的不为0,就有效,则计数++;判断计数是否为3,如果为3,则计数归0,剩余人数-1,该位置赋值为0(*p=0,即退出圈子),并且进行p++。一直到remain剩余人数为1,遍历数组找到不为0的数,即最后留下的。

==43.初识结构体==
结构体的定义:

结构体知识:

//在C语言中定义:
typedef struct {
   
    int x;
    char y;
    float z;    
}student;

//在C++语言中定义:
struct student{
   
    int x;
    char y;
    float z;    
};

结构体的大小:
int+char+float=4+1+8=13

结构体定义并赋值(初始化默认为 0):
student a1;
a1.x=1;a1.y=2;a1.z=3;

student a1={
   1,2,3};

分析:本题创造学号,姓名,3门课的成绩(数组),使用for循环即可解决问题。

==44.链表之头插法==

//链表知识:
//定义方式一:
typedef struct LNode {
   
    int data;
    struct LNode *next;
} LNode,*Liuklist;

//定义方式二(更优):
typedef struct LNode {
   
    int data;
    struct LNode *next;
} LNode;

typedef LNode *Liuklist;
//LNode 结构体定义了单链表节点的结构,包含 data 和 next 两个成员。
//Liuklist 被定义为指向 LNode 的指针,因此它可以用来表示单链表。
int mian(){
   
    // 创建三个节点
    LNode* node1 = (LNode*)malloc(sizeof(LNode));
    LNode* node2 = (LNode*)malloc(sizeof(LNode));
    LNode* node3 = (LNode*)malloc(sizeof(LNode));

    // 设置节点数据
    node1->data = 10;
    node2->data = 20;
    node3->data = 30;

    // 连接节点
    node1->next = node2;
    node2->next = node3;
    node3->next = NULL;

     // 释放内存
    free(node3);
    free(node2);
    free(node1);

    return 0;
}

本题采用头插法,头插法常用于逆置

分析:返回值为指针,所以函数为Liuklist 函数名(Liuklist &L){}; (==如果链表发生变化,则加&==)
进入函数,先创建一个节点s(LNode s)用来存储要加入的数。如果L空指针, L=(Node ) malloc(sizeof (LNode)); //L是头节点,链表头节点分配内存空间,并指向空,并使L的的next指向空即L->next=NULL;输入第一个加入的数,如果不是特定的数,则开始插入。给s分配新的内存空间,令s的data为加入的数。使s的next指向L的next,而L的next指向s。(先s连接后面,防止断链)

//核心代码
s = (Lnode *)malloc(sizeof(Lnode)); 
s -> data=x;
s -> next=L->next;
L -> next=s;

==45.链表之尾插法==
尾插法需要找到链表的尾节点,然后将新节点插入到尾节点之后。
分析:同理,返回值为指针,所以函数为Liuklist 函数名(Liuklist &L){}; (==如果链表发生变化,则加&==)
进入函数,先创建一个节点s(LNode s)用来存储要加入的数。如果L空指针, L=(Node ) malloc(sizeof (LNode)); //L是头节点,链表头节点分配内存空间,并指向空,并使L的的next指向空即L->next=NULL;(==初始化一个r始终指向L的尾部==)输入第一个加入的数,如果不是特定的数,则开始插入。给s分配新的内存空间,令s的data为加入的数。使s的next指向r的next,而r的next指向s。令r=s,即指向最后一位。

s = (Lnode *)malloc(sizeof(Lnode)); 
s->data=x;
s->next=r->next;
r->next=s;
r=s;

查找尾节点的一种方法:

while (r->next != nullptr) {
   
    r = r->next;
}

代码实现

#include <stdio.h>

int leap(int year){
   
    return year%4==0 && year%100!=0 || year%400==0;
}

typedef struct {
   
    int num;
    char name[30];
    float scare[3];    
}student;

int main()
{
   

//    41.给出年、月、日,计算该日是该年的第几天解析:需要掌握函数:判断是否为闰年
    int year,month,day,day_th;
    printf("输入年月日的值:");
    scanf("%d %d %d",&year,&month,&day);
    int day_tab[13]={
   0,31,28,31,30,31,30,31,31,30,31,30,31};
    for(int i=1;i<month;i++){
   
        day+=day_tab[i];
    }
    if(leap(year) && month>=3){
   
        day++;
    }
    printf("是该年的第%d天",day);

//42.(约瑟夫环问题)有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3 的人退出圈子,问最后留下的是原来第几号的那位,用指针实现。
    int n,count=0;
    printf("请输入n的值:");
    scanf("%d",&n);
    int people[n],remain=n,*p=NULL;  //remain剩余人数 
    for(int i=0;i<n;i++){
   
        people[i]=i+1;   //赋初值 
    }
    while(remain>1){
   
        p=people;    
        while(p!=people+n){
   
            if(*p!=0){
   
                count++;
                if(count==3){
   
                    *p=0;
                    count=0;
                    remain--;
                }
            }
            p++;
        }
    }
    for(int i=0;i<n;i++){
   
        if(people[i]!=0){
   
            printf("最后留下的是原来第%d号",people[i]);
        }
    }

//43.有 10 个学生,每个学生的数据包括学号,姓名,3门课的成绩,从键盘输人10个学生数据.要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3 门课程成绩平均分数)。
    student stu[10];
    int idex=0;
    float sum=0,max_sum=0,aver_1=0,aver_2=0,aver_3=0;
    for(int i=0;i<10;i++){
   
        printf("请输入第%d个人的信息:",i+1);
        scanf("%d %s %f %f %f",&stu[i].num,&stu[i].name,&stu[i].scare[1],&stu[i].scare[2],&stu[i].scare[3]);
        sum=0;
        for(int j=0;j<3;j++){
   
            sum += stu[i].scare[j];
        }
        if(sum>max_sum){
   
            max_sum = sum;
            idex=i;
        }
        aver_1+=stu[i].scare[1];
        aver_2+=stu[i].scare[2];
        aver_3+=stu[i].scare[3];
    }
    aver_1 /= 10;
    aver_2 /= 10;
    aver_3 /= 10;
    printf("3门课程总平均成绩:%.2f   %.2f   %.2f",aver_1,aver_2,aver_3);
    printf("最高分的学生的数据:\n学号:%d 姓名:%d 3门课的成绩:%.2f %.2f %.2f",stu[idex].num,stu[idex].name,stu[idex].scare[1],stu[idex].scare[2],stu[idex].scare[3]);

//    44.采用头插法建立单链表  头插法常用与逆置 

typedef struct LNode {
   
    int data;
    struct LNode *next;
} LNode;

typedef LNode *Liuklist;
//LNode 结构体定义了单链表节点的结构,包含 data 和 next 两个成员。Liuklist 被定义为指向 LNode 的指针,因此它可以用来表示单链表。

Liuklist list_Headiusert(Liuklist &L) {
     //改结构加& 
    LNode *s;  // 加入s 
    int x;    //s的值 
    L=(Node *) malloc(sizeof (LNode));  //L是头节点,链表头节点分配内存空间,并指向空 
    L->next=NULL;
    printf("请输入数据(输入9999结束): ");
    scanf("%d",&x);
    while (x!=9999) {
   
        s = (Lnode *)malloc(sizeof(Lnode)); 
        s -> data=x;
        s -> next=L->next;
        L -> next=s;
        printf("请输入数据(输入9999结束): ");
        scanf("%d", &x);
        if (x == 9999) {
   
            break; 
        }
    }

    return L; 
}

//    45.采用尾插法建立单链表 
Liuklist list_Tailiusert(Liuklist &L) {
     //改结构加& 
    LNode *s,*r;
    int x;
    L=(Node *) malloc(sizeof (LNode));
    L->next=NULL;
    r=L;
    printf("请输入数据(输入9999结束): ");
    scanf("%d",&x);
    while (x!=9999) {
   
        s = (Lnode *)malloc(sizeof(Lnode)); 
        s->data=x;
        s->next=r->next;
        r->next=s;
        r=s;
        printf("请输入数据(输入9999结束): ");
        scanf("%d", &x);
        if (x == 9999) {
   
            break; 
        }
    }

    return L; 
}
    return 0;
}

总结

本文介绍了五个数据结构问题及其C语言实现,这些问题涉及日期计算、约瑟夫环问题、学生成绩处理、以及单链表的头插法和尾插法操作。这些算法问题覆盖了基础算法、数组、指针、结构体和链表的多个方面,展示了数据结构在解决实际问题中的应用。

日期计算问题要求我们根据给定的年、月、日计算该日是该年的第几天。这个问题的解决关键在于判断是否为闰年,并根据月份累加天数。

约瑟夫环问题是一个经典的递归问题,要求我们找出在特定报数规则下最后留下的人的编号。这个问题的解决可以通过模拟报数过程,使用数组和指针来实现。

学生成绩处理问题要求我们输入10个学生的数据,并计算输出3门课程的总平均成绩以及最高分学生的信息。这个问题的解决涉及到结构体的使用,以及对数组和结构体成员的操作。

单链表的头插法和尾插法问题是链表操作的基础,头插法常用于逆置链表,而尾插法则需要找到链表的尾部进行插入。这两个问题的解决展示了链表操作的灵活性和多样性。

这些算法的实现不仅展示了C语言在处理数组、指针和链表时的能力,也体现了算法设计的基本思想,如条件判断、循环控制和递归。通过这些算法的学习,我们可以更好地理解数据结构和算法的基本概念,提高解决实际问题的能力。

总的来说,这些算法问题不仅锻炼了编程能力,也加深了对数据结构和算法的理解。通过这些问题的解决,我们可以逐步提高自己的编程技能,为将来的学习和工作做好准备。这些算法的掌握对于计算机专业的学生和软件开发人员来说都是非常重要的。通过这些练习,我们可以逐步提高自己的编程技能,为将来的学习和工作做好准备。同时,这些问题的解决也体现了算法在处理数据时的灵活性和效率,为我们在实际开发中遇到类似问题提供了解决思路。

目录
相关文章
|
1月前
|
机器学习/深度学习 算法 C语言
【趣学C语言和数据结构100例】11-15
本文介绍了五个C语言编程问题及其实现,包括矩阵对角线元素之和、有序数组插入、数组逆序、杨辉三角输出和魔方阵生成。每个问题不仅涉及基本的数组操作,还涵盖了算法设计的核心思想,如循环、条件判断和递归。通过解决这些问题,读者可以加深对C语言和数据结构的理解,提升编程技能。这些问题的解决过程展示了如何有效处理数组和矩阵,以及如何利用算法优化程序性能,为实际应用提供了宝贵的实践经验。
56 4
【趣学C语言和数据结构100例】11-15
|
24天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
37 1
|
1月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
45 4
|
1月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
43 4
|
1月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
39 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