练习题题解(结构体+链表)

7-3 通讯录排序

题目描述

输入n个朋友的信息,包括姓名、生日、电话号码,本题要求编写程序,按照年龄从大到小的顺序依次输出通讯录。题目保证所有人的生日均不相同。

输入格式

输入第一行给出正整数n(<10)。随后n行,每行按照“姓名 生日 电话号码”的格式给出一位朋友的信息,其中“姓名”是长度不超过10的英文字母组成的字符串,“生日”是yyyymmdd格式的日期,“电话号码”是不超过17位的数字及+、-组成的字符串。

输出格式:

按照年龄从大到小输出朋友的信息,格式同输出。

输入样例:

3
zhang 19850403 13912345678
wang 19821020 +86-0571-88018448
qian 19840619 13609876543

输出样例:

wang 19821020 +86-0571-88018448
qian 19840619 13609876543
zhang 19850403 13912345678

题目分析

本题直接使用一个结构体来记录每个人的信息,然后按照年龄排序可以根据,每个人出生日期进行降序排序(出生日期小年龄大),如1989年出生比1990年出生的年龄大。

代码实现

#include<stdio.h>
#include<string.h>
typedef struct Humen{
    char name[20];
    char birth[9];
    char phino[20];
}humen;//结构体定义每个人的信息
humen humen1[20];//记录输入的信息
humen humen2;//用于中间交换
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){//依次输入姓名、出生日期、电话号码
        scanf("%s",humen1[i].name);
        scanf("%s",humen1[i].birth);
        scanf("%s",humen1[i].phino);
    }
    for(int i=0;i<n-1;i++){//冒泡排序对出生日期进行升序排序(出生日期越小年龄越大)
        for(int j=0;j<n-i-1;j++){
            if(strcmp(humen1[j].birth,humen1[j+1].birth)>0){
                humen2=humen1[j];
                humen1[j]=humen1[j+1];
                humen1[j+1]=humen2;
            }
        }
    }
    for(int i=0;i<n;i++){//输出打印结果
        printf("%s ",humen1[i].name);
        printf("%s ",humen1[i].birth);
        printf("%s\n",humen1[i].phino);
    }
    return 0;
}

7-10 两个有序链表的合并

题目描述

已知两个非递减有序单链表La与Lb,编写程序把La和Lb合并为新的非递减有序链表Lc。
单链表的类型描述:

typedef int ElemType;
typedef struct lnode
{ ElemType data;
  struct lnode *next;
 }Lnode,*LinkList;

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非递减有序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出合并后新的有序链表,数字间用空格分开,开头和结尾不能有多余空格;若新链表为空,输出NULL。

输入样例:

1 3 5 -1
2 4 6 8 10 -1

输出样例:

1 2 3 4 5 6 8 10

输入样例:

-1
-1

输出样例:

NULL

题目分析

本题是一道基础链表题,通过一次比较链表节点大小,然后插入新的链表,最后输出新链表。本题也可以通过普通数组来完成操作。具体看下面代码及注释。

链表代码

#include<stdio.h>
#include<stdlib.h>
typedef struct CodeList{
    int num;
    struct CodeList* next;
}CodeList;//节点
CodeList* CreateNewCode(int x){//创建新的节点
    CodeList* newCode=(CodeList*)malloc(sizeof(CodeList));
    newCode->num=x;
    newCode->next=NULL;
    return newCode;
}
void CreateList(CodeList** pphead,int x)//创建链表
{
    CodeList* newCode=CreateNewCode(x);
    if(*pphead==NULL){
        *pphead=newCode;
        return;
    }
    CodeList* ptail=*pphead;
    while(ptail->next){
        ptail=ptail->next;//遍历链表
    }
    ptail->next=newCode;//插入节点
}
void PrintList(CodeList* phead)//打印链表
{
    CodeList* pcur=phead;
    while(pcur){
        if(pcur->next==NULL){
            printf("%d",pcur->num);
            break;
        }
        printf("%d ",pcur->num);
        pcur=pcur->next;
    }
}
int main()
{
    int count1=0,count2=0;//记录节点数量
    CodeList* plist1=NULL;
    while(1){//创建链表1
        int x;
        scanf("%d",&x);
        if(x==-1)break;
        CreateList(&plist1,x);
        count1++;
    }
    CodeList* plist2=NULL;
    while(1){//创建链表2
        int x;
        scanf("%d",&x);
        if(x==-1)break;
        CreateList(&plist2,x);
        count2++;
    }
    if(count1==0&&count2==0){
        printf("NULL");
        return 0;
    }
    CodeList* newlist=NULL;//新链表
    CodeList* newtail=NULL;
    CodeList* pcur1=plist1;
    CodeList* pcur2=plist2;
    while(pcur1&&pcur2){
        if(pcur1->num<=pcur2->num){//节点依次比较
            if(newlist==NULL){
                newlist=pcur1;
                newtail=pcur1;
            }else{
                newtail->next=pcur1;
                newtail=newtail->next;
            }
            pcur1=pcur1->next;
        }else{
            if(newlist==NULL){
                newlist=pcur2;
                newtail=pcur2;
            }else{
                newtail->next=pcur2;
                newtail=newtail->next;
            }
            pcur2 = pcur2->next;
        }
    }
    if(pcur1){//当链表1节点有剩余,直接使后面的节点接上新链表
        newtail->next=pcur1;
    }
    if(pcur2){//当链表2节点有剩余,直接使后面的节点接上新链表
        newtail->next=pcur2;
    }
    PrintList(newlist);
    return 0;
}

数组代码

#include<stdio.h>
int main()
{
    int num1[10001];//创建足够大的数组
    int num2[10001];
    int count1=0,count2=0;
    for(int i=0;;i++){//数组1数据输入
        scanf("%d",&num1[i]);
        if(num1[i]==-1){
            num1[i]='\0';
            break;
        }
        count1++;
    }
    for(int i=0;;i++){//数组2数据输入
        scanf("%d",&num2[i]);
        if(num2[i]==-1){
            num2[i]='\0';
            break;
        }
        count2++;
    }
    int num3[20001],count3=0;//合并后数组,count3为数组元素数量
    int p=0,q=0;//记录数组1和数组2排入数组3的数据数量
    for(int i=0;num1[p]!='\0'&&num2[q]!='\0';i++){//比较大小排入新数组
        if(num1[p]<=num2[q]){
            num3[i]=num1[p];
            p++;
        }else{
            num3[i]=num2[q];
            q++;
        }
        count3++;
    }
    if(num1[p]!='\0'){//数组1有剩余继续排入
        while(num1[p]!='\0'){
            num3[count3]=num1[p];
            p++,count3++;
        }
    }
    if(num2[q]!='\0'){//数组2有剩余继续排入
        while(num2[q]!='\0'){
            num3[count3]=num2[q];
            q++,count3++;
        }
    }
    if(count1==0&&count2==0){//输入数组没有数据输出空指针
        printf("NULL");
        return 0;
    }
    for(int i=0;i<count3;i++){
        if(i==count3-1){
            printf("%d",num3[i]);
            break;
        }
        printf("%d ",num3[i]);
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值