第十一周作业

第一题

这一题的想法是让大家熟悉并掌握结构体的定义和使用,这块就不多赘述,结构体的定义可以帮助我们将想要的一些信息整合起来,防止进行排序或者其他变量的赋值和交换的时候出现问题。
简单谈一下稳定性这个概念,稳定性就是数组中值相等的两个元素,在排序完成之后,他们之间的相对顺序不发生改变,常见排序算法的稳定性可以参考这个地方。常见排序算法总结归纳

#include<iostream>
#include<cstdlib>
using namespace std;

struct candidate{
    string name ;
    int count ;
    void init()
    {
        cin >> name;
        count = 0;
    }
    void swap(candidate &other) {
        name.swap(other.name);
        int tmp = count;
        count = other.count;
        other.count = tmp;
    }
};

int main()
{
    int n,m;
    cin >> n >>m;
    candidate record[n]={};
    for(int i=0;i<n;i++)
    {
        record[i].init();
    }
    string cur;
    for(int i = 0; i < m;i++)
    {
        cin >>cur;
        for(int j =0 ;j < n;j++)
        {
            if(record[j].name == cur)//string类可以这么写,char数字要自己用strcpy
                record[j].count++;
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j = n - 1 ; j > i; j--)
        {
            if(record[j].count >record[j - 1].count)
                record[j].swap(record[j -1]);
        }
    }
    for(int i = 0;i<n;i++)
    {
        cout <<record[i].name<<" "<<record[i].count<<" ";
    }
    return 0;
}

第二题

这个结构体存在的问题比较集中的地方在于最后的地址那,有些同学会觉得题目给的例子中有5个字符串就使用cin>>string直接读取5个字符串,但其实题目中没有说明地址这块会分为5个字符串,而且测试集也可以看到字符串的数量是不稳定的,所有这块还是使用cin.getline比较好。要依据不同的输入格式及时调整

#include <iostream>

using namespace std;

struct AddressBook
{
    struct BirthDay
    {
        int year, month, day;
    };

    char name[21];
    BirthDay birth;
    long long phonenum;
    char address[51];

    void init() {
        cin >> name >> birth.year >> birth.month >> birth.day >> phonenum; 
        cin >> ws; cin.getline(address, 51, '\n');
    }

    void disp() {
        printf("%s %d %d %d %lld %s\n", name, birth.year, birth.month, birth.day, phonenum, address);
    }

    int birthday() {
        // 辅助 sort
        return birth.year * 10000 + birth.month * 100 + birth.day;
    }
};


void bubbleSort(AddressBook* A, int n) {
    // sort by birthday
    
    for (int i=n-1; i>=0; --i) {
        bool exist_swap = false;
        for (int j=0; j<i; ++j) {
            if (A[j].birthday() < A[j+1].birthday()) swap(A[j], A[j+1]), exist_swap = true;
        }
        if (! exist_swap) break;
    }
}



int main(int argc, char const *argv[])
{
    int n;
    cin >> n;

    AddressBook books[10];

    for (int i=0; i<n; ++i) {
        books[i].init();
    }

    bubbleSort(books, n);
    
    for (int i=0; i<n; ++i) {
        books[i].disp();
    }
    

    return 0;
}

第三题

这个题目的错误还是比较明显的,首先是错误的输出这个不多说,其次是while循环中这一部分
在这里插入图片描述
下节课老师会讲到这一部分的内容,这是链表中很经典的一种建表方法,被称为头插法,也就是将新生成的结点插入链表的表头,具体的可以看老师ppt上有关该部分的动画加深理解
第二个地方就是输出的for循环那,明显可以看出按照给的条件来看最后会少输出一个结点,所以要修改一下判定条件,这些地方修改完毕之后就可以通过了
在这里插入图片描述

#include <iostream>
using namespace std;
struct List
{
    int num;
    List *next;
};
int main()
{
    List *head, *p, *q;
    int num;
    head = NULL;
    // cout << "请输入若干个正整数(-1结束)\n";
    cin >> num;
    while(num != -1)
    {
        p = new List;
        p->num = num;
        p->next = head;
        head = p;
        cin >> num;
    }
    // cout << "按照输入顺序逆序输出\n";
    for(p = head; p != NULL; p = p->next)
    {
        cout << p->num << " ";
    };
    cout << endl;
    for(p = head; p != NULL; p = q)
    {
        q = p->next;
        delete p;
    }
    return 0;
}

第四题

这个题目主要理解翻转链表要干啥,基本思路就是将下一个结点的next指针指向自己同时又能保证链表的递归遍历,这样就可以比较轻松得出下面的算法:

  • 首先定义pre,cur ,next三个指针(注意与结点内的next进行区分),cur初值为head。
  • 遍历过程中首先要判断cur是否为空,不为空则让next暂存下一个结点的地址(也就是cur->next),cur的next指针指回到pre,这样就完成了一次当前结点的指针的翻转,随后更新pre,cur的值即可
    对第一个结点的操作可以看下面几张图(注意next只起到一个暂时存放地址的作业,所以一次操作前next值为啥都无所谓)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
ListNode* reverseList(ListNode* head) {
    /********* Begin *************/
    ListNode* prev = NULL, *curr = head, *next;
    while (curr) {
        next = curr->next; curr->next = prev;
        prev = curr; curr = next;
    }
    return prev;
    /********* End *************/
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值