编辑代码

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

// 定义链表节点结构体
struct ListNode {
    int val;
    struct ListNode *next;
};

// 在链表中插入节点
/*在C语言中,函数传参时传递的是值,而不是变量本身。这意味着如果我们在函数内部修改传入的参数,实际上只是修改了函数内部参数的副本,而不是原始参数本身。
当我们需要在函数内部修改链表头节点时,需要使用二级指针。一级指针只能指向一个变量,而二级指针可以指向一个指针变量,也就是可以 //修改指针变量本身的值//。
在这个例子中,//insertNode函数需要修改链表头节点,而链表头节点是一个指针变量//。如果我们只传递一个一级指针head,那么在函数内部修改head的值只是修改了head指向的链表节点的值,而不是链表头节点本身的值。
因此,我们需要使用二级指针来传递链表头节点的地址,这样在函数内部修改head的值时,实际上是修改了链表头节点本身的值。
*/
void insertNode(struct ListNode **head, int position, int val) {
    // 创建新节点
    struct ListNode *newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;

    // 如果链表为空,则新节点为头节点
    if (*head == NULL) {
        *head = newNode;
        return;
    }

    // 如果插入位置为0,则新节点为头节点
    if (position == 0) {
        newNode->next = *head;
        *head = newNode;
        return;
    }

    // 找到插入位置的前一个节点
    struct ListNode *prevNode = *head;
    for (int i = 0; i < position - 1 && prevNode->next != NULL; i++) {
        prevNode = prevNode->next;
    }

    // 如果插入位置超出链表长度,则新节点为尾节点
    if (prevNode->next == NULL) {
        prevNode->next = newNode;
        return;
    }

    // 插入新节点
    newNode->next = prevNode->next;
    prevNode->next = newNode;
}

int main() {
    // 创建链表头节点
    struct ListNode *head = NULL;

    // 在链表中插入节点
    insertNode(&head, 0, 1);
    insertNode(&head, 1, 3);
    insertNode(&head, 1, 2);
    insertNode(&head, 3, 4);

    // 遍历链表并打印节点的值
    struct ListNode *p = head;
    while (p != NULL) {
        printf("%d ", p->val);
        p = p->next;
    }
    printf("\n");

    return 0;
}