带两个约束的链表插入

马丁·洛佩兹

尝试按字母顺序将学生插入链表学生有姓名和年龄。它们按名称排序,如果名称相同,则按年龄排序。

我可以把名字部分弄对,但年龄有点棘手。崩溃的部分是第一个 if 语句。当新学生与列表中的第一个人同名时,他们必须按年龄排序,但是当我尝试使用该代码时,它会给我一个分段错误。其余代码有效。
这是code

Student* insert(Student* student, Student* list)
{
Student* current;

if (list == NULL || (precedes(student->name, list->name) > 0) || strcmp(student->name, list->name) == 0){    
    if (strcmp(list->name, student->name) == 0) {  // goes wrong here i think
        if (student->age < list->age) {
            student->next = list;
            list = student;
        } else {
            student->next = list->next;
            list->next = student;
        }
    } else {
        student->next = list;
        list = student;
    }
} else {
    current = list;
    while(current->next != NULL && (precedes(current->next->name, student->name) > 0)) {
        current= current->next;
    }
    if (current->next != NULL && strcmp(current->next->name, student->name) == 0) {
        if (current->next->age > student->age){
            student->next = current->next;
            current->next = student;
        } else {
            student->next = current->next->next;
            current->next->next = student;
        }
    } else {
        student->next = current->next;
        current->next = student;
    }

}
return list;
}
克雷格

你做得比它需要的要困难得多。

您有一个明显的情况,即取消引用空指针是确定的,因此确保未定义的行为也是如此。在您的代码中:

if (list == NULL || (precedes(student->name, list->name) > 0) || strcmp(student->name, list->name) == 0){    
    if (strcmp(list->name, student->name) == 0) {  // goes wrong here i think

如果由于为list == NULL而输入该 if 块,您将立即取消引用该空指针以访问其nameage成员。随之而来的是未定义的行为,你实际上很幸运你的程序崩溃了(它可能更糟;它可能已经成功并让你相信你没有犯错)。


效用比较函数

由于两个Student对象的比较可能两阶段而不是一个阶段,这一任务才变得复杂所以要做两件事:

  • 编写一个比较函数,得出不等大条件的具体标准。
  • 在需要比较两个Student结构的任何地方使用该函数

这样的比较函数看起来像这样:

int cmp_Student(const Student *lhs, const Student *rhs)
{
    int cmp = strcmp(lhs->name, rhs->name);
    if (cmp == 0)
        cmp = (lhs->age < rhs->age) ? -1 : rhs->age < lhs->age;
    return cmp;
}

< 0lhs引用 a返回Student“小于” rhs,当lhs等于返回rhs> 0lhs“大于”时返回rhs

使用它,然后您可以编写一个简单的指针到指针遍历算法,该算法遍历列表中的指针以寻找合适的插入点,然后使用指针到指针来实现这一点。list为 NULL 时,这也消除了特殊大小写的需要,因为您真的不在乎。

Student *insert(Student *student, Student *list)
{
    Student **pp = &list;
    while (*pp && cmp_Student(student, *pp) < 0)
        pp = &(*pp)->next;

    student->next = *pp;
    *pp = student;

    return list;
}

即使你不这样做insert,你仍然可以使用cmp_Student你自己的算法。无论如何,仔细阅读上面的内容以了解其工作原理是值得的,而调试器是一种很好的方法。

显然,如果您坚持使用现有实现,则需要修复该空指针取消引用代码路径,因为这显然是错误的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

两个链表的总和

来自分类Dev

使用两个结构体 C 编程的单向链表插入函数

来自分类Dev

找到两个双向链表的交集

来自分类Dev

随机合并两个链表

来自分类Dev

合并两个排序的链表

来自分类Dev

合并两个排序的单链表

来自分类Dev

合并两个已排序的链表

来自分类Dev

合并两个已排序的链表

来自分类Dev

比较 Java 中的两个链表

来自分类Dev

合并两个短链表

来自分类Dev

为什么两个不同值的插入会导致唯一约束违规?

来自分类Dev

参数约束以实现两个接口

来自分类Dev

如何约束两个标签

来自分类Dev

对两个不同列组合的约束

来自分类Dev

带两个边界的圆

来自分类Dev

带blockproc的两个输出

来自分类Dev

带螺纹的两个矩阵的乘积

来自分类Dev

带两个按钮的输入字段

来自分类Dev

带两个元音的Grep单词

来自分类Dev

带两个按钮的HTML表单

来自分类Dev

两个 SSD 带或不带 LVM?

来自分类Dev

带FK的表是指带两个PK的表

来自分类常见问题

具有基本接口相同的两个约束,但两个约束不能相同

来自分类Dev

具有基本接口相同的两个约束,但两个约束不能相同

来自分类Dev

结合两个相等链表的Runner技术

来自分类Dev

联接两个双链表的正确方法

来自分类常见问题

如何分别交错这两个链表?

来自分类Dev

了解c中两个链表实现之间的区别

来自分类Dev

合并两个链表时出现错误