📌  相关文章
📜  用于从线段链接列表中删除中间点的 C 程序(1)

📅  最后修改于: 2023-12-03 14:56:19.285000             🧑  作者: Mango

从线段链接列表中删除中间点的 C 程序

这是一份用于从线段链接列表中删除中间点的 C 程序。我们可以使用这个程序来删除线段连接列表中的任何中间点,并且可以用于减小链表的大小和优化链表的性能。

算法原理

该程序使用的算法原理是快慢指针。我们用两个指针,fast 指针每次移动两个节点,slow 指针每次移动一个节点。当快指针走到尾部时,慢指针就来到了链表的中间节点。此时,我们删除慢指针指向的节点,就完成了链表中间节点的删除。

C 代码实现
#include <stdio.h>
#include <stdlib.h>

struct node {
    int data;
    struct node *next;
};

void removeMiddleNode(struct node *head) {
    struct node *slowPtr = head;
    struct node *fastPtr = head;
    struct node *prevSlowPtr = NULL;

    while (fastPtr != NULL && fastPtr->next != NULL) {
        fastPtr = fastPtr->next->next;
        prevSlowPtr = slowPtr;
        slowPtr = slowPtr->next;
    }

    prevSlowPtr->next = slowPtr->next;
    free(slowPtr);
}

int main() {
    struct node *head = malloc(sizeof(struct node));
    struct node *second = malloc(sizeof(struct node));
    struct node *third = malloc(sizeof(struct node));
    struct node *fourth = malloc(sizeof(struct node));

    head->data = 1;
    head->next = second;

    second->data = 2;
    second->next = third;

    third->data = 3;
    third->next = fourth;

    fourth->data = 4;
    fourth->next = NULL;

    printf("Before removing middle node: ");
    struct node *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    removeMiddleNode(head);

    printf("After removing middle node: ");
    current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    return 0;
}
解释代码
  1. 定义一个节点结构体。
struct node {
    int data;
    struct node *next;
};
  1. 实现函数 removeMiddleNode
void removeMiddleNode(struct node *head) {
    struct node *slowPtr = head;
    struct node *fastPtr = head;
    struct node *prevSlowPtr = NULL;

    while (fastPtr != NULL && fastPtr->next != NULL) {
        fastPtr = fastPtr->next->next;
        prevSlowPtr = slowPtr;
        slowPtr = slowPtr->next;
    }

    prevSlowPtr->next = slowPtr->next;
    free(slowPtr);
}

此方法中有三个指针:

  • slowPtr 从链表头开始遍历,一次移动一个节点。
  • fastPtr 从链表头开始遍历,一次移动两个节点。
  • prevSlowPtr 用于保存 slowPtr 上一个节点的位置,以便在删除中间节点后将其上一个节点的 next 指针指向正确的下一个节点。

该方法使用一个 while 循环来遍历链表,当快指针 fastPtr 到达链表末尾时,慢指针 slowPtr 恰好来到链表的中间位置。然后,我们用 prevSlowPtr 将链表的中间节点删除,并释放中间节点的内存。删除此节点后,链表中间节点就已经被成功删除了。

  1. 创建一个主函数并进行测试
int main() {
    struct node *head = malloc(sizeof(struct node));
    struct node *second = malloc(sizeof(struct node));
    struct node *third = malloc(sizeof(struct node));
    struct node *fourth = malloc(sizeof(struct node));

    head->data = 1;
    head->next = second;

    second->data = 2;
    second->next = third;

    third->data = 3;
    third->next = fourth;

    fourth->data = 4;
    fourth->next = NULL;

    printf("Before removing middle node: ");
    struct node *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    removeMiddleNode(head);

    printf("After removing middle node: ");
    current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    return 0;
}

此主函数定义了一个包含四个节点的链表,每个节点包含一个整数。然后,它显示链表的初始状态。接下来,调用 removeMiddleNode 函数来删除链表中的中间节点,然后再次打印链表的内容以检查是否已成功删除了中间节点。最后,该程序会正常退出。

以上就是实现从线段链接列表中删除中间点的 C 程序的方法。这个程序是用快慢指针算法实现的,可以帮助我们删除线段连接列表中的任何中间点。