删除单链表中第i个节点

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cyuyanenen/article/details/51366185

单链表的删除操作是将单链表的第i个节点删去。具体步骤如下:
(1)找到节点ai-1的存储位置p,因为在单链表中节点ai的存储地址是在其直接前趋节点ai-1的指针域next中;
(2)令p->next指向ai的直接后继节点ai+1;
(3)释放节点ai的空间;

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

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


// 尾插法创建单链表(带头节点)
NODE *createEnd(int arr[], int len)
{
    NODE *head = (NODE *)malloc(sizeof(NODE)); // 生成头节点
    head->next = NULL;
    NODE *end = head;  // 尾指针初始化

    for (int i = 0; i < len; i++) {

        NODE *p = (NODE *)malloc(sizeof(NODE)); // 为每个数组元素建立一个节点
        p->data = arr[i];
        end->next = p;  // 将节点p插入到终端节点之后
        end = p;
    }

    end->next = NULL;  // 单链表建立完毕,将终端节点的指针域置空

    return head;
}


// 删除单链表中第i个节点
NODE *delete(NODE *head, int i)
{
    NODE *p = head;

    int j = 1;
    while (p->next && j < i) {
        p = p->next;
        ++j;
    }

    if (p->next == NULL || j > i) { // 经过循环,若最终p为空,或i为0或负数时,都说明位置不合理;
        printf("Position Error\n");
        return 0;
    }


    NODE *temp = p->next;
    p->next = temp->next;

    free(p);

    return head;
}
// 注: (1)设单链表的长度为n,则单链表删除第i个节点时,必须保证 1<= i <= n,否则不合法;
//     (2)当 i=n+1 时,虽然被删除节点不存在,但其前趋节点却存在,它是终端节点;所以,被删节点的直接前趋*p存在,并不意味着被删节点就一定存在,仅当*p存在(即p != NULL)且*p不是终端节点(即p->next != NULL)同时满足 j <= i时,才能确定被删节点存在。此时,算法的时间复杂度是O(n)。


// 单链表打印
void print(NODE *head)
{
    if (head == NULL) return;

    NODE *p = head->next;
    while (p != NULL) {
        printf("%d\n", p->data);
        p = p->next;
    }
}

int main(void)
{
    int arr[] = {1,2,3,4,5,6,7};
    int len = sizeof(arr)/sizeof(int);

    NODE *head = createEnd(arr, len);

    // 删除前
    print(head);


    delete(head, 5);
    // 删除后
    print(head);

    return 0;
}
展开阅读全文

没有更多推荐了,返回首页