当前位置: 首页 > article >正文

PTA数据结构题目:链表操作集合

寻找结点

在这里插入图片描述

插入结点

在这里插入图片描述

错误分析

while (prev != NULL && prev->Next != P)
为什么我写成
while (prev->Next != P && prev != NULL)
的时候会发生段错误,这两种写法逻辑上不是一样的吗?

野指针

逻辑顺序导致的潜在风险
在 C 语言中,逻辑与(&&)运算符是短路求值的。这意味着当计算A && B时,如果A为假,就不会再计算B了,因为整个表达式已经确定为假。
当你写成while (prev->Next!= P && prev!= NULL)时,如果prev是NULL,那么prev->Next这个操作会导致段错误。因为NULL指针是不能进行成员访问操作(->)的。而while (prev!= NULL && prev->Next!= P)这种写法先判断prev是否为NULL,只有当prev不为NULL时,才会去访问prev->Next,这样就避免了空指针访问的问题,是一种更安全的写法。

删除结点

删除结点

代码

#include <stdio.h>
#include <stdlib.h>

#define ERROR NULL
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode
{
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

Position Find(List L, ElementType X);
List Insert(List L, ElementType X, Position P);
List Delete(List L, Position P);

int main()
{
    List L;
    ElementType X;
    Position P, tmp;
    int N;

    L = NULL;
    scanf("%d", &N);
    while (N--)
    {
        scanf("%d", &X);
        L = Insert(L, X, L);
        if (L == ERROR)
            printf("Wrong Answer\n");
    }
    scanf("%d", &N);
    while (N--)
    {
        scanf("%d", &X);
        P = Find(L, X);
        if (P == ERROR)
            printf("Finding Error: %d is not in.\n", X);
        else
        {
            L = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if (L == ERROR)
                printf("Wrong Answer or Empty List.\n");
        }
    }
    L = Insert(L, X, NULL);
    if (L == ERROR)
        printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    tmp = Insert(L, X, P);
    if (tmp != ERROR)
        printf("Wrong Answer\n");
    tmp = Delete(L, P);
    if (tmp != ERROR)
        printf("Wrong Answer\n");
    for (P = L; P; P = P->Next)
        printf("%d ", P->Data);
    return 0;
}

Position Find(List L, ElementType X)
{
    while (L != NULL)
    {
        if (L->Data == X)
        {
            return L;
        }
        L = L->Next;
    }
    return ERROR;
}
List Insert(List L, ElementType X, Position P)
{
    Position new = (Position)malloc(sizeof(struct LNode));
    if (new == NULL)
    {
        return ERROR;
    }
    new->Data = X;
    new->Next = NULL;
    if (P == NULL)
    {
        if (L == NULL)
        {
            return new;
        }
        Position last = L;
        while (last->Next != NULL)
        {
            last = last->Next;
        }
        last->Next = new;
        return L;
    }
    if (P == L)
    {
        new->Next = L;
        return new;
    }
    Position prev = L;
    //反过来写会造成野指针错误,访问空指针
    while (prev != NULL && prev->Next != P) // 这里不同
    {
        prev = prev->Next;
    }
    if (prev == NULL)
    {
        free(new);
        printf("Wrong Position for Insertion\n");
        return ERROR;
    }
    new->Next = prev->Next;
    prev->Next = new;
    return L;
}
List Delete(List L, Position P)
{
    if (P == NULL)
    {
        printf("Wrong Position for Deletion\n");
        return ERROR;
    }
    if (P == L)
    {
        List tmp = L; // 不同
        L = L->Next;
        free(tmp);
        return L;
    }
    Position prev = L;
    while (prev != NULL && prev->Next != P)
    {
        prev = prev->Next;
    }
    if (prev == NULL)
    {
        printf("Wrong Position for Deletion\n");
        return ERROR;
    }
    prev->Next = P->Next;
    free(P);
    return L;
}

http://www.kler.cn/a/450491.html

相关文章:

  • 第十五章 C++ 数组
  • WebAssembly与WebGL结合:高性能图形处理
  • C#(委托)
  • 汽车IVI中控开发入门及进阶(47):CarPlay开发
  • Git 的基本概念和使用
  • 增量训练(持续学习)
  • 近实时”(NRT)搜索、倒排索引
  • Unity3d 基于UGUI和VideoPlayer 实现一个多功能视频播放器功能(含源码)
  • GitLab 停止为中国区用户提供 GitLab.com 账号服务
  • kong网关使用pre-function插件,改写接口的返回数据
  • 隧道可视化技术开拓智能建设新航道
  • 基于Spring Boot的摄影器材租赁回收系统
  • 神经网络图像隐写术:用AI隐藏信息的艺术
  • 1小时放弃Rust(1): Hello-World
  • *【每日一题 基础题】 [蓝桥杯 2024 省 B] 好数
  • 逻辑的诗:类与对象(下)
  • JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
  • Hydra配置文件的书写语法
  • Ruby+Selenium教程
  • 今天最新早上好问候语精选大全,每天问候,相互牵挂,彼此祝福
  • 预约参观华为基地,见证行业巅峰
  • Jmeter分布式压力测试
  • 7-4 字符串的冒泡排序
  • VMware vCenter保姆级安装部署(VMware VCenter Nanny Level Installation and Deployment)
  • Mac的M2芯片运行lightgbm报错,其他python包可用,x86_x64架构运行
  • 如何绘制网络拓扑图?附详细分类解说和用户案例!