C语言算法-解答删除链表的倒数第 N 个结点问题的C语言实现
 
            
            题目
给定一个链表,删除链表的倒数第 N 个结点,并返回链表的头结点。
引言
删除链表的倒数第 N 个结点问题需要注意边界条件和特殊情况的处理。我们可以使用双指针的方法来解决这个问题,其中一个指针先走 N 步,然后两个指针同时向前走,直到第一个指针到达链表末尾。这样,第二个指针指向的结点就是要删除的结点。解决这个问题需要对链表进行遍历和指针操作。
算法思路
我们将使用双指针的方法来解决删除链表的倒数第 N 个结点问题。
算法的步骤如下:
- 创建一个虚拟头结点 dummy,并将其指向链表的头结点。这样可以方便处理删除头结点的情况。
- 使用两个指针 fast和slow,初始化它们都指向虚拟头结点dummy。
- 让 fast先向前移动 N+1 步,将两个指针之间相隔 N 个结点。
- 同时移动 fast和slow,直到fast到达链表末尾。这样,slow就指向要删除的结点的前一个结点。
- 修改指针,将 slow的下一个结点指向要删除的结点的下一个结点,实现删除操作。
- 返回链表的头结点,即虚拟头结点 dummy的下一个结点。
代码实现
下面是使用C语言实现的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
    int val;
    struct ListNode* next;
} ListNode;
ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode* dummy = (ListNode*)malloc(sizeof(ListNode));
    dummy->next = head;
    ListNode* fast = dummy;
    ListNode* slow = dummy;
    for (int i = 0; i < n + 1; i++) {
        fast = fast->next;
    }
    while (fast != NULL) {
        fast = fast->next;
        slow = slow->next;
    }
    ListNode* toRemove = slow->next;
    slow->next = slow->next->next;
    free(toRemove);
    ListNode* result = dummy->next;
    free(dummy);
    return result;
}
void printList(ListNode* head) {
    ListNode* current = head;
    while (current != NULL) {
        printf("%d ", current->val);
        current = current->next;
    }
    printf("\n");
}
int main() {
    // 创建示例链表: 1 -> 2 -> 3 -> 4 -> 5
    ListNode* head = (ListNode*)malloc(sizeof(ListNode));
    head->val = 1;
    ListNode* node1 = (ListNode*)malloc(sizeof(ListNode));
    node1->val = 2;
    head->next = node1;
    ListNode* node2 = (ListNode*)malloc(sizeof(ListNode));
    node2->val = 3;
    node1->next = node2;
    ListNode* node3 = (ListNode*)malloc(sizeof(ListNode));
    node3->val = 4;
    node2->next = node3;
    ListNode* node4 = (ListNode*)malloc(sizeof(ListNode));
    node4->val = 5;
    node3->next = node4;
    node4->next = NULL;
    printf("Original List: ");
    printList(head);
    int n = 2;
    ListNode* result = removeNthFromEnd(head, n);
    printf("After Removal: ");
    printList(result);
    // 释放内存
    while (result != NULL) {
        ListNode* temp = result;
        result = result->next;
        free(temp);
    }
    return 0;
}算法分析
该算法只需要对链表进行一次遍历,所以时间复杂度为 O(L),其中 L 是链表的长度。
空间复杂度为 O(1),算法只使用了常数级别的额外空间。
示例和测试
示例输入1:
链表: 1 -> 2 -> 3 -> 4 -> 5,n = 2示例输出1:
删除倒数第二个结点后的链表: 1 -> 2 -> 3 -> 5示例输入2:
链表: 1,n = 1示例输出2:
删除倒数第一个结点后的链表: 空链表示例输入3:
链表: 1 -> 2,n = 2示例输出3:
删除倒数第二个结点后的链表: 2总结
本文使用C语言实现了解答删除链表的倒数第 N 个结点问题的代码。通过使用双指针的方法,我们能够删除链表中倒数第 N 个结点,并返回删除后的链表。该算法的时间复杂度为 O(L),空间复杂度为 O(1)。
 
          
          
         