删除链表中的第i个元素

img


我在网上搜的是缺少分号或者缺少头文件,但是我试过好几个头文件,struct.h啊啥的,都没有成功,劳烦大家了

供参考:

img

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/1047107
  • 你也可以参考下这篇文章:计算一个struct占用的内存字节数
  • 除此之外, 这篇博客: 【C语言进阶深度学习记录】二十 结构体大小计算与结构体内存布局的详细方法中的 2.1 struct结构体大小计算案例分析-结构体中没有结构体 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    如下面的代码:

    • 24-3.c
    #include <stdio.h>
    
    #pragma pack(2)
    struct Test1
    {
        char  c1;
        short s;
        char  c2;
        int   i; 
    };
    #pragma pack()
    
    #pragma pack(4)
    struct Test2
    {
        char  c1;
        char  c2;
        short s;
        int   i;
    };
    #pragma pack()
    
    int main()
    {
        printf("sizeof(Test1) = %d\n", sizeof(struct Test1));
        printf("sizeof(Test2) = %d\n", sizeof(struct Test2));
    
        return 0;
    }
    
    • 编译运行结果为:

    sizeof(Test1) = 10
    sizeof(Test2) = 8

    • 结果分析1–Test1:

    对于结构体Test1,2字节对齐,按照上述三个计算条件有:

    struct Test1
    {              //对齐方式             大小         起始地址                占用的内存地址位置      
        char  c1;       2          大于     1            0                            0            
        short  s;       2          等于     2            2(被对齐参数2整除)            2~3           
        char  c2;       2          大于     1(对齐参数)   4                            4            
        int   i;        2(对齐参数) 小于     4            6(被对齐参数2整除)            6~9
    };  
    
    1. Test1的对齐方式是2字节。

    然后根据:

    1. 每个成员按其类型大小和pack参数中较小的一个 进行对齐。比如上面的起始地址计算那里,都是被对齐参数2整除,这个2是类型大小和pack参数中较小的一个

      2.1 偏移地址必须能被对齐参数整除

    这一条规则计算每个成员的起始地址。如上面的计算。

    1. 最后再看总体大小是否是对齐参数的整数倍。上面Test1 大小是10,是对齐参数2的整数倍
    • 结果分析2–Test2

    对于结构体Test2,4字节对齐,按照上述三个计算条件有:

    struct Test2
    {              //对齐方式         大小           起始地址                   占用的内存地址位置      
        char  c1;       4      大于    1(对齐参数)       0                             0            
        char  c2;       4      大于    1(对齐参数)       1(被对齐参数1整除)             1           
        short s;        4      大于    2(对齐参数)       2(被对齐参数2整除)             2~3          
        int   i;        4      等于    4(对齐参数)       4(被对齐参数4整除)             5~7
    };
    
    1. Test2 的对齐方式是4字节对齐

    然后再根据:

    1. 每个成员按其类型大小和pack参数中较小的一个 进行对齐。比如上面的起始地址计算那里,对齐参数分别为1,1,2,4

      2.1 偏移地址必须能被对齐参数整除

    这一条规则计算每个成员的起始地址。如上面的计算。

    1. 最后再看总体大小是否是对齐参数的整数倍。上面Test2 大小是8,是对齐参数4的整数倍

    经过上面的两个结构体大小的计算,可以很容易的画出其内存图

  • 您还可以看一下 Abel小智老师的嵌入式开发系统学习路线 从基础到项目 精品教程 工程师必备课程 物联网课程中的 学会使用struct关键词小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    答案:

    删除链表中的第i个元素,需要遍历链表找到第i个元素,并将其从链表中删除。

    具体的步骤如下:

    1. 定义链表结构体和节点结构体,代码如下:
    struct Node {
        int val;
        struct Node* next;
    };
    
    struct LinkedList {
        struct Node* head;
    };
    
    1. 实现删除第i个元素的函数,代码如下:
    void deleteNode(struct LinkedList* list, int index) {
        if (list == NULL || list->head == NULL || index < 1) {
            return;
        }
        // 如果要删除头节点
        if (index == 1) {
            struct Node* p = list->head;
            list->head = p->next;
            free(p);
            return;
        }
        // 找到待删除节点的前一个节点
        struct Node* prev = list->head;
        for (int i = 1; i < index - 1 && prev->next != NULL; i++) {
            prev = prev->next;
        }
        // 检查节点是否存在
        if (prev->next == NULL) {
            return;
        }
        // 删除节点
        struct Node* p = prev->next;
        prev->next = p->next;
        free(p);
    }
    
    1. 测试代码
    int main() {
        struct LinkedList list;
        struct Node* node1 = (struct Node*)malloc(sizeof(struct Node));
        node1->val = 1;
        struct Node* node2 = (struct Node*)malloc(sizeof(struct Node));
        node2->val = 2;
        struct Node* node3 = (struct Node*)malloc(sizeof(struct Node));
        node3->val = 3;
    
        node1->next = node2;
        node2->next = node3;
        node3->next = NULL;
    
        list.head = node1;
    
        printf("before delete: ");
        struct Node* p = list.head;
        while (p != NULL) {
            printf("%d ", p->val);
            p = p->next;
        }
        printf("\n");
    
        deleteNode(&list, 2);
    
        printf("after delete: ");
        p = list.head;
        while (p != NULL) {
            printf("%d ", p->val);
            p = p->next;
        }
        printf("\n");
    
        return 0;
    }
    

    输出结果为:

    before delete: 1 2 3 after delete: 1 3

    注解说明:

    在函数deleteNode中,首先进行了一些边界检查,如果链表为空或者index<1就直接返回。然后特判了要删除头节点的情况,直接将头节点指针指向下一个节点,然后释放被删除的节点。接着就从第一个节点开始遍历,遍历到第i-1个节点时即为要删除的节点的前一个节点,然后判断要删除的节点是否存在,如果存在就将删除节点的前一个节点指向删除节点的下一个节点,然后释放被删除的节点。最后在主函数中测试了一下代码,首先遍历输出链表,然后删除第二个节点,最后再遍历输出链表。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633