[剑指offer][leetcode]面试题18:删除链表的节点

27 篇文章 0 订阅
14 篇文章 0 订阅
本文介绍了一种在O(1)时间内删除单向链表中指定节点的方法,通过分析节点位置(头节点、中间节点、尾节点),并提供了相应的C语言实现代码。同时,对比了不同情况下的时间复杂度,并复习了malloc与new的区别及.与->运算符的用法。
摘要由CSDN通过智能技术生成

1. 在O(1)时间内删除链表节点

给定一个单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。

  1. 首先定义一个结构体表示链表元素
typedef struct ListNode* Link;
//写一个包括链表结构的结构体
struct ListNode
{
    int val;
    struct ListNode* next;
};
  1. 将链表元素存储在数组中,使用头插法创建链表
//创建链表
Link CreatLink(int a[],int length)
{
    Link head;
    //malloc和new的用法区别

    //这样是有头节点的链表
    // struct ListNode 和*Link的区别
    head=(Link)malloc(sizeof(struct ListNode));
    head->next=NULL;

    Link phead;
    phead=head;
    for(int i=0;i<length;i++)
    {
        Link t;
        t=(Link)malloc(sizeof(struct ListNode));
        t->val=a[i];
        phead->next=t;
        phead=t;
        //phead建立前一个节点的位置
        //只是一个指针 没有分配实际的内存空间
        t->next=NULL;
    }
    //head指向下一个表示跳过头节点
    //head=head->next;
    return head;
}
  1. 分析需要删除的节点在哪个位置?
    平常需要删除一个节点,需要遍历链表找到对应的节点,需要 O ( n ) O(n) O(n)
    需要删除的节点无非三个地方:1.头节点 2.中间节点 3.尾节点
    如果是头节点,则说明这个链表只有一个元素。因为对于待删除的节点来说,指出的是指针。如果两个指针相等,那么则表示是一个元素。所以返回NULL。如果是中间节点,我们其实不必去找该节点的前一个节点,可以用该节点的下一个节点去覆盖当前节点,然后删除其后续节点,代价为 O ( 1 ) O(1) O(1)。如果是尾节点,就没有办法,因为不知道前一个节点是什么,需要遍历链表,将前一个节点指向NULL,代价为 O ( N ) O(N) O(N)。综合来说, O ( 1 ) ∗ n − 1 + O ( n ) = O ( 1 ) O(1)*n-1+O(n)=O(1) O(1)n1+O(n)=O(1),代价仍然是 O ( 1 ) O(1) O(1).
//指向指针的指针表示什么 应该是一个指向头节点的指针
//.和->的区别
void DeleteNode(ListNode** pListNode,ListNode* pToBeDeleted)
{
    //判断是否为空链表 如果头节点为空则为空
    if(pListNode==NULL)
        return;
    if(pToBeDeleted==NULL)
        return;

    //讨论被删除的这个节点是哪里的
    //1.头节点 相等表示只有一个节点 那么删除之后就为空
    if(*pListNode==pToBeDeleted)
    {

        delete pToBeDeleted;
        pToBeDeleted=NULL;
        *pListNode=NULL;
    }
    //2.不是尾节点 采用覆盖的办法
    else if(pToBeDeleted->next!=NULL)
    {
        //p指向链表
        ListNode* p=pToBeDeleted->next;
        pToBeDeleted->val=p->val;
        pToBeDeleted->next=p->next;
        p->next=NULL;
        //delete的作用?
        delete p;
    }
    //3.是尾节点 没有办法覆盖 需要知道上一个
    //不知道把哪个指向null
    else
    {
        ListNode* p=*pListNode;
        while(p->next->next!=NULL)
        {
            p=p->next;

        }
        p->next=NULL;
        delete pToBeDeleted;
    }

}

2. 知识点温习

malloc与new,delete

十点区别,来源网上(malloc与new的区别
在这里插入图片描述

.与->

点运算符的左操作数是结构体。
箭头运算符的左操作数是指向结构体的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值