C++:Leetcode-链表-707设计链表

C++:Leetcode-链表-707设计链表

熟悉巩固链表的各种操作



题目

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。


思路分析

1、创建节点
2、索引获取节点值
3、添加头结点
4、添加尾节点
5、插入节点
6、删除节点

此题注意index是从0开始,linkedSize是实际长度,插入节点别漏情况,记得更新linkedSize即可

代码

/*
Leetcode-707设计链表
自行设计链表的一些功能,加强对链表的理解与运用能力

1、创建节点
2、索引获取节点值
3、添加头结点
4、添加尾节点
5、插入节点
6、删除节点

此题注意index是从0开始,linkedSize是实际长度,插入节点别漏情况,记得更新linkedSize即可
*/

#include "iostream"
#include "vector"
using namespace std;

class MyLinkedList
{
    
    
private:
    /* data */
public:
    //创建节点
    class linkedNode
    {
    
    
    public:
        int val;
        linkedNode *next;
        linkedNode() : val(0), next(nullptr) {
    
    }
        linkedNode(int x) : val(x), next(nullptr) {
    
    }
        linkedNode(int x, linkedNode *l_next) : val(x), next(l_next) {
    
    }
    };
    linkedNode *dummyHead; //虚拟头结点
    int linkedSize;
    //初始化虚拟头结点
    MyLinkedList()
    {
    
    
        dummyHead = new linkedNode(0);
        linkedSize = 0;
    }

    //初始化链表
    linkedNode *createList(vector<int> &nums)
    {
    
    
        linkedNode *head = new linkedNode(nums[0]);
        linkedNode *p = head;
        for (int i = 1; i < nums.size(); i++)
        {
    
    
            p->next = new linkedNode(nums[i]);
            p = p->next;
        }
        //     delete p; //不能delete,有bug,当没有进入for,p的内存空间可能跟head一样,也会把head空间删除掉,return head出错!!!!!
        linkedSize += nums.size();
        dummyHead->next = head;
        return head; //返回头节点
    }

    //索引获取节点值
    //获取链表中第 index 个节点的值
    //注意:index是从0开始,linkedSize就是实际长度
    int get(int index)
    {
    
    
        if (index > (linkedSize - 1) || index < 0)
        {
    
    
            return -1;
        }
        linkedNode *current = dummyHead->next; //指向头节点
        while (index--)
        {
    
    
            current = current->next;
        }
        return current->val;
    }

    //添加头结点
    void addAtHead(int val)
    {
    
    
        linkedNode *newHead = new linkedNode(val);
        newHead->next = dummyHead->next; //新头结点指向老头结点
        dummyHead->next = newHead;       //虚拟头结点指向新头结点
        linkedSize++;
    }

    //添加尾节点
    void addAtTail(int val)
    {
    
    
        linkedNode *newTail = new linkedNode(val);
        linkedNode *current = dummyHead;

        while (current->next != nullptr)
        {
    
    
            current = current->next;
        }
        current->next = newTail;
        linkedSize++;
    }

    //插入节点
    //在链表中的第 index 个节点之前添加值为 val 的节点
    void addAtIndex(int index, int val)
    {
    
    
        linkedNode *newNoed = new linkedNode(val);
        if (index == linkedSize) //节点插入末尾

        {
    
    
            addAtTail(val);
        }
        else if (index > linkedSize) //不插入节点

        {
    
    
            return;
        }

        else if (index == 0) //插入头部
        {
    
    
            addAtHead(val);
        }
        else //插入中间节点
        {
    
    
            linkedNode *current = dummyHead;
            while (index--)
            {
    
    
                current = current->next;
            }
            newNoed->next = current->next;
            current->next = newNoed;
            linkedSize++;
        }
    }

    //删除节点
    //删除链表中的第 index 个节点。
    //index从0开始,第0节点为头结点
    //linkedSize为实际长度
    void deleteAtIndex(int index)
    {
    
    
        //索引无效或没有节点
        if (index < 0 || index >= linkedSize)
        {
    
    
            return;
        }
        else
        {
    
    
            linkedNode *current = dummyHead; // 现节点为虚拟节点,即头结点的上一个节点,方便后续寻找index的上一个节点
            //遍历寻找第index个节点的上一个节点
            while (index--)
            {
    
    
                current = current->next;
            }
            linkedNode *temp = current->next; //赋值给temp,方便delete
            current->next = current->next->next;
            delete temp;
            linkedSize--;
        }
    }

    //打印链表
    void printlist()
    {
    
    
        linkedNode *current = dummyHead->next; //现节点为头结点
        while (current != nullptr)             //注意不是current->next!=nullptr ,因为尾节点的指针指向nullptr
        {
    
    
            cout << current->val << "\t";
            current = current->next;
        }
        cout << endl;
    }
};

int main(int argc, const char **argv)
{
    
    
    vector<int> nums = {
    
    1};
    MyLinkedList mylist;
    mylist.createList(nums);
    mylist.printlist();

    mylist.addAtTail(3);
    mylist.printlist();

    mylist.addAtIndex(1, 2); //有问题
    mylist.printlist();

    cout << mylist.get(1) << endl; //有问题

    mylist.deleteAtIndex(1);
    mylist.printlist();

    cout << mylist.get(1) << endl;

    return 0;
}

总结

刷题巩固对链表的掌握,进一步加强对指针的运用和理解
参考代码随想录
https://www.programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html#%E4%BB%A3%E7%A0%81

猜你喜欢

转载自blog.csdn.net/Bellwen/article/details/128422061