链表——力扣203移除链表元素,707 设计链表,206反转链表

链表相关基础知识

此部分来自代码随想录

题目讲解

一. 力扣203——移除链表元素

注意:

1.删除元素时添加一个头节点,这样就不用再写一个当删除节点时原头结点时的代码了。

2.当前节点不要设置为与val进行比较的节点,设置成上一个节点更方便循环条件的判断

3.注意需要手动管理内存,delete删除的节点(Java,python不用)

4.当p节点的下一个节点满足删除条件并且被删除后,不需要进行p = p->next操作,因为我们是对p->next节点进行判断的。

5.最后需要更新head节点!!(我总是忘记)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* Head = new ListNode(0);
        Head->next = head;
        ListNode *p = Head;//设置当前节点的上一个节点方便设置循环条件
        while(p->next != NULL)
        {
            if(p->next->val == val)//结束后p不需要换到下一个节点,因为我们查看的就是p的下一个节点
            {
                ListNode* q = p->next;
                p->next = q->next;
                delete q;
            }
            else
            {
                p = p->next;
            }
        }
        head = Head->next;//当原head被删除时,head节点需要改变
        delete Head;
        return head;

    }
};

二.力扣707——设计链表

需要注意的都在代码里备注了,主要是删除指针之后要记得指向NULL


class MyLinkedList {
public:
    struct LinkNode
    {
        int val;
        LinkNode* next;
        LinkNode(int x):val(x),next(nullptr){}
    };
    
    MyLinkedList() //初始化一个链表
    {
        Head =  new LinkNode(0);
        sizee = 0;
    }
    
    int get(int index) //若index有效返回下标为index的值
    {
        if(index < 0 || index >= sizee)
            return -1;
        LinkNode *p = Head->next;
        while(index--)
        {
            p = p->next;
        }
        return p->val;
    }
    
    void addAtHead(int val) //在链表的最前端建立数值为val的新节点
    {
        LinkNode *q = new LinkNode(val);
        q->next = Head->next;
        Head->next = q;
        sizee++;
    }
    
    void addAtTail(int val) //在链表末端建立数值为val的新节点
    {
        LinkNode *p = Head;
        while(p->next != nullptr)
        {
            p = p->next;
        }
        LinkNode *q = new LinkNode(val);
        p->next = q;
        q->next = nullptr;
        sizee++;
    }
    
    void addAtIndex(int index, int val) //在index结点之前插入数值为val的节点
    {
        if(index >= 0 && index <= sizee)
        {
            LinkNode *p = Head;
            while(index--)
            {
                p = p->next;
            }
            LinkNode *q = new LinkNode(val);
            q->next = p->next;
            p->next = q;
            sizee++;
        }
    }
    
    void deleteAtIndex(int index) {
        if(index >= 0 && index < sizee)
        {
            LinkNode *p = Head;
            while(index--)
            {
                p = p->next;
            }
            LinkNode *tmp = p->next;
            p->next = tmp->next;
            sizee--;
            delete tmp;
            //delete命令指示释放了tmp指针原本所指的那部分内存,
            //被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
            //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
            //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
            tmp = nullptr;
        }
    }
private:
    LinkNode *Head;
    int sizee;
    
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

其中addatindex函数我一开始写的是这样的(如下)

也就是把index等于链表长度的情况分出来写的(其实没有必要),我这里就是复制的在尾部添加节点的代码,但一直跑不对,不知道哪里有问题,有大佬可以帮忙解答一下吗?

void addAtIndex(int index, int val) //在index结点之前插入数值为val的节点
    {

        if(index == sizee)
        {
            LinkNode *p = Head;
            while(p->next != nullptr)
            {
                p = p->next;
            }
            LinkNode *q = new LinkNode(val);
            p->next = q;
            q->next = nullptr;
            sizee++;
        }
        if(index >= 0 && index < sizee)
        {
            LinkNode *p = Head;
            while(index--)
            {
                p = p->next;
            }
            LinkNode *q = new LinkNode(val);
            q->next = p->next;
            p->next = q;
            sizee++;
        }
    }

三.力扣206——反转链表

注意:

我一开始用的是三个指针分别指向第0,1,2个节点,后来发现访问内存出现了问题,因为链表可能是一两个节点,甚至没有结点,所以错误。

正确代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *pre = NULL;
        ListNode *q = head;
        ListNode *k;
        while(q)
        {
            k = q->next;
            q->next = pre;
            pre = q;
            q = k;
        }
        return pre;
    }
};

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值