0
点赞
收藏
分享

微信扫一扫

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

【趣学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;
}

举报

相关推荐

0 条评论