抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。


707. 设计链表

思路

  • 构造含有头节点的双链表

学习点

  • 链表的基本操作

代码

struct DNode
{
    int val;
    DNode* next;
    DNode* prev;

    DNode(int _val): val(_val) {}
    DNode(int _val, DNode* _next, DNode* _prev): 
                val(_val), next(_next), prev(_prev) {}
};

// 带头节点
class MyLinkedList {
public:
    MyLinkedList() {
        // 初始化一个空节点
        this->head = new DNode(-1, nullptr, nullptr);
        this->size = 0;
    }
    
    int get(int index) {
        if (index < 0 || index >= this->size ||
            this->head->next == nullptr)
        {
            return -1;
        }
        auto p = this->head;
        while (index >= 0 && p != nullptr)
        {
            p = p->next;
            --index;
        }
        return p->val;
    }
    
    void addAtHead(int val) {
        DNode* new_node = new DNode(val, nullptr, nullptr);
        // 设置前驱后继
        new_node->next = this->head->next;
        new_node->prev = this->head;
        // 修改链表前驱后继
        if (this->head->next != nullptr)
        {
            this->head->next->prev = new_node;
        }
        this->head->next = new_node;
        // 增加个数
        ++this->size;
    }
    
    void addAtTail(int val) {
        int count = this->size;
        auto p = this->head;
        // 移动到末尾元素
        while (count > 0)
        {
            p = p->next;
            --count;
        }
        // 添加元素
        DNode* new_node = new DNode(val, nullptr, nullptr);
        // 设置前驱
        new_node->prev = p;
        // 链接节点
        p->next = new_node;
        // 增加个数
        ++this->size;
    }
    
    void addAtIndex(int index, int val) {
        if (index > this->size || index < 0)
        {
            return;
        }
        if (index == this->size)
        {
            addAtTail(val);
            return;
        }
        auto p = head;
        // 遍历到 index - 1 处的元素
        while (index > 0)
        {
            p = p->next;
            --index;
        }
        // p 指向 index - 1 处的元素
        DNode* new_node = new DNode(val, nullptr, nullptr);
        p->next->prev = new_node;
        new_node->next = p->next;
        new_node->prev = p;
        p->next = new_node;
        // 增加个数
        ++this->size;
    }
    
    void deleteAtIndex(int index) {
        if (index < 0 || index >= this->size)
        {
            return;
        }
        auto p = head;
        while (index >= 0)
        {
            p = p->next;
            --index;
        }
        // p 指向要删除的节点
        // 前后节点链接
        p->prev->next = p->next;
        if (p->next != nullptr)
        {
            p->next->prev = p->prev;
        }
        // 释放 p
        delete p;
        // 减少个数
        --this->size;
    }

private:
    DNode* head;
    int size;
};

/**
 * 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);
 */



本站采用 Volantis 主题设计