【力扣探索】链表——双链表

双链表的不同

与单链表唯一不同的地方在于结构体中增加了指向前一节点的prev指针

操作简介

可以与单链表相同的方式访问数据:

  1. 非常量级时间访问随机位置。
  2. 从头部遍历获得目标结点。
  3. 在最坏的情况下,时间复杂度将是 O(N)。

与单链表的相似之处

  1. 它们都无法在常量时间内随机访问数据。
  2. 它们都能够在 O(1) 时间内在给定结点之后或列表开头添加一个新结点。
  3. 它们都能够在 O(1) 时间内删除第一个结点。

但是删除给定结点(包括最后一个结点)时略有不同

  1. 在单链表中,它无法获取给定结点的前一个结点,因此在删除给定结点之前我们必须花费 O(N) 时间来找出前一结点。在双链表中,这会更容易,因为我们可以使用“prev”引用字段获取前一个结点。因此我们可以在 O(1) 时间内删除给定结点。

练习

设计双链表

题目链接: 707. 设计链表
解题思路

  1. 类似于单链表,按部就班实现即可,使用虚拟头节点可以简化讨论,注意增删时prev与next相互赋值的顺序,插入新节点时,先安排好新节点的prev,next指针,再去处理前节点的next与后节点的prev。

代码

//定义双链表节点的数据结构
class BiListNode{
public:
    int val;
    BiListNode *next, *prev;
    BiListNode(int x){
        this->val = x;
        this->next = NULL;
        this->prev = NULL;
    }
    BiListNode(){
        this->next = NULL;
        this->prev = NULL;
    }
};

//具体的双链表
class MyLinkedList {
public:
    /** Initialize your data structure here. */
    BiListNode *dummy_head;
    int length;
    MyLinkedList() {
        dummy_head = new BiListNode(-1);
        length = 0;
    } 
    /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
    int get(int index) {
        if(index >= length || index < 0) return -1;
        BiListNode *p = dummy_head;
        for(int i = 0; i < index+1; ++i)
            p = p->next;
        return p->val;
    } 
    /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
    void addAtHead(int val) {
        BiListNode* newhead = new BiListNode(val);
        newhead->prev = dummy_head;
        newhead->next = dummy_head->next;
        dummy_head->next = newhead;
        if(newhead->next != NULL)
            newhead->next->prev = newhead;
        length++;
    }  
    /** Append a node of value val to the last element of the linked list. */
    void addAtTail(int val) {
        BiListNode* newtail = new BiListNode(val);
        BiListNode* p = dummy_head;
        while(p->next != NULL) p = p->next;
        p->next = newtail;
        newtail->prev = p;
        length++;
    }   
    /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
    void addAtIndex(int index, int val) {
        if(index < 0 || index > length) return;
        BiListNode *cur = new BiListNode(val);
        BiListNode *p = dummy_head;
        for(int i = 0; i < index; ++i){
            p = p->next;
        }
        if(p->next == NULL){
            addAtTail(val);
        }else{
            cur->prev = p;
            cur->next = p->next;
            p->next = cur;
            cur->next->prev = cur;
            length++;
        }
    }   
    /** Delete the index-th node in the linked list, if the index is valid. */
    void deleteAtIndex(int index) {
        if(index < 0 || index >= length) return;
        BiListNode *p = dummy_head;
        for(int i = 0; i < index; ++i){
            p = p->next;
        } 
        p->next = p->next->next;
        length--;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值