代码随想录训练营第三天|链表理论基础,203.移除链表元素 ,707.设计链表 ,206.反转链表

203.移除链表元素

文章链接:代码随想录 (programmercarl.com)

视频链接:手把手带你学会操作链表 | LeetCode:203.移除链表元素_哔哩哔哩_bilibili

这道题目还挺简单的 Carl哥讲的特别清晰 !!!!

考察单链表的删除元素的操作 分为两种解法:

1.不使用虚拟头节点

2.使用虚拟头节点

移除头节点和非头节点的操作是不一样的,若加一个虚拟头节点,代码可以实现统一,能方便许多!

1、不使用虚拟头节点

a.删除头节点

注意:头节点不可以为空;C++语言写的代码,删除结点之后,记得释放内存哦!

       //不使用虚拟头节点
       //a.删除头节点
       while(head!=NULL&&head->val==val)
       {
           ListNode* temp=head;
           head=head->next;
           delete temp;
       }

在这个代码中,为什么head不等于空,因为要操纵头结点的值,如果为空就是操纵头指针了

head->val等于要删除的值 

这两个都是删除头结点时要满足的条件

b.删非头节点

创建一个指针 指向头节点,因为删除的是非头节点,指针需要指向头节点,如果指向其他节点,删除非头节点后,又因为是单链表,头节点没做记录,没办法将链表连接起来了!

//b.删非头节点
       ListNode* cur=head;
       while(cur!=NULL&&cur->next!=NULL)
       {
           if(cur->next->val==val)
           {
               ListNode* temp=cur->next;
               cur->next=cur->next->next;
               delete temp;
           }
           else{
               cur=cur->next;
           }
       }

2、使用虚拟头节点

在头节点之前创建一个虚拟头节点,不管是删除头节点还是非头节点,都可以用统一的一段代码,只需要释放掉删除节点的内存空间和创建的虚拟头节点的内存空间!

这里的cur仍然指向链表的第一个节点,即为创建的虚拟头节点

        //使用虚拟头节点
        ListNode* dummyhead=new ListNode(0);
        dummyhead->next=head;
        ListNode* cur=dummyhead;
        while(cur->next!=NULL)
        {
            if(cur->next->val==val)
            {
                ListNode* temp=cur->next;
                cur->next=cur->next->next;
                delete temp;
            }
            else{
                cur=cur->next;
            }
        }
        return dummyhead->next;
        delete dummyhead;

 707.设计链表

文章链接:代码随想录 (programmercarl.com)

视频链接:帮你拿下反转链表 | LeetCode:206.反转链表 | 双指针法 | 递归法_哔哩哔哩_bilibili

虚拟头节点是一个局部节点变量,程序结束后自动释放内存,并没有造成内存泄漏。//这句话参考链表第二天:虚拟头节点_为什么定义了虚拟头节点之后,释放时要用虚拟-CSDN博客

以下代码参考代码随想录 代码随想录 (programmercarl.com)

1、获取第N个节点的值

首先对N做一个合法判断,如果n小于0或者n大于链表节点数量,则是不合法的,创造cur指针指向头节点,然后while循环获取节点值即可

    //1.获取第n节点的值
    int get(int index)
    {
        if(index<0||index>(size-1))
        {
            return -1;
        }
        //创造cur指针, 将该指针指向头节点 利用while循环遍历 找到第n个节点的值
        LinkedNode * cur=_dummyHead->next;
        while(index)
        {
            cur=cur->next;
            index--;
        }
        return cur->val;
    }

2、头部插入节点

创造一个新的节点,将该节点插入到链表的头部,作为头节点。

注意:先将新节点指向原来的头节点,再将虚拟头节点指向新节点!!!!

    //2.头部插入节点
    void addAtHead(int val)
    {
        LinkedNode* newnode=new LinkedNode(val);
        newnode->next=_dummyHead->next;
        _dummyHead->next=newnode;
        size++;
    }

3、尾部插入节点

如何找到尾部节点;cur->next=NULL的话,此时,cur就是尾部节点,将cur->next指向新节点即可。

//3.尾部插入节点
    void addAtTail(int val)
    {
        LinkedNode* newnode=new LinkNode(val);
        LinkedNode* cur=_dummyHead;
        while(cur->next!=NULL)
        {
            cur=cur->next;
        }
        cur->next=newnode;
        size++;
    }

4、第n个节点前插入节点

先找到第N个节点,cur->next指向第n个节点,cur指向第n-1个节点,然后新节点指向cur->next,cur指向新节点

//4.在n个节点前插入节点
    void addAtIndex(int index,int val)
    {
    if(index>size)
    {
        return;
    }
    LinkedNode* cur=_dummyHead;
    LinkedNode* newnode=new LinkedNode(val);//创造一个新节点并赋予val
    while(index)//在这里必须让cur指向第n-1个节点 如果cur指向了第n个节点 将新节点插入时 第n-1个节点没做记录
    {
        cur=cur->next;
        index--;
    }
    newnode->next=cur->next;
    cur->next=newnode;
    size++;
    }

5、删除第n个节点

先找到第N个节点,cur->next指向第n个节点,cur指向第n-1个节点,将cur指向第n+1节点,释放第n个节点的内存空间

//5.删除第n个节点
    void deleteAtIndex(int index)
    {
        if(index<0||index>=size)
        {
            return;
        }
        LinkedNode* cur=_dummyHead;
        while(index--)
        {
            cur=cur->next;
        }
        LinkedNode *temp=cur->next;
        cur->next=cur->next->next;
        delete temp;
        temp=nullptr;
        size--;
    }

206.反转链表

文章链接:代码随想录 (programmercarl.com)

视频链接:帮你拿下反转链表 | LeetCode:206.反转链表 | 双指针法 | 递归法_哔哩哔哩_bilibili

有两种方法

1、双指针

cur指向头节点,pre指向cur的前一个节点即为空节点,临时指针指向cur->next

反转操作:

temp=cur->next

cur->next=pre

pre=cur

cur=temp

返回新链表的头节点pre

注意:当cur为空指针的时候,即为遍历结束

2、递归 一一对应双指针 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值