正在载入交互式动画窗口请稍等

双链表-带头结点 可视化交互式动画版

图码-数据结构可视化动画版

在双向链表中插入新节点与在链表中插入新节点非常相似。 维护前一个节点的链接需要一些额外的工作。 可以通过四种方式将节点插入双向链表:

  • 在DLL的前面。 
  • 在两个节点之间
    • 在给定节点之后。
    • 在给定节点之前。
  • 在 DLL 的末尾。

在双向链表的前面添加一个节点:

新节点始终添加到给定链表的头之前。 该任务可以通过以下 5 个步骤来执行:

  1. 首先,分配一个新节点(例如 new_node )。
  2. 现在将所需的数据放入新节点中。
  3. 使new_node 的next 指向双向链表的当前头。
  4. 使当前头的前一个指向 new_node
  5. 最后,将 head 指向 new_node

插图:

请参见下图,其中 E 被插入到双向链表的开头。

dll_add_front

下面是在链表前面插入节点的5个步骤的实现:

C

// Given a reference (pointer to pointer) to the head
// of a list and an int, inserts a new node
// on the front of the list.
void push(struct Node** head_ref, int new_data)
{
    // 1. allocate node
    struct Node* new_node
        = (struct Node*)malloc(sizeof(struct Node));
 
    // 2. put in the data
    new_node->data = new_data;
 
    // 3. Make next of new node as head and previous as NULL
    new_node->next = (*head_ref);
    new_node->prev = NULL;
 
    // 4. change prev of head node to new node
    if ((*head_ref) != NULL)
        (*head_ref)->prev = new_node;
 
    // 5. move the head to point to the new node
    (*head_ref) = new_node;
}


              

C++

Java

Python3

C#

Javascript

时间复杂度: O(1)
辅助空间: O(1)

在两个节点之间添加一个节点:

又分为以下两部分:

在双向链表中的给定节点之后添加一个节点:

我们将获得一个指向节点的指针 prev_node ,并且新节点将插入到给定节点之后。 这可以通过以下 6 个步骤来完成:

  1. 首先创建一个新节点(例如 new_node )。
  2. 现在将数据插入新节点。
  3. 将new_node 的下一个指向 prev_node 的下一个
  4. 将prev_node 的下一个 指向 new_node
  5. 将new_node 的前一个 指向 prev_node
  6. 将新节点的前一个指针更改为 new_node

插图:

请参见下图,其中“ E ”被插入到“ B ”之后。

dll_add_middle

下面是在链表中给定节点之后插入节点的 7 个步骤的实现:

C

// Given a node as prev_node, insert a new node
// after the given node
void insertAfter(struct Node* prev_node, int new_data)
{
    // Check if the given prev_node is NULL
    if (prev_node == NULL) {
        printf("the given previous node cannot be NULL");
        return;
    }
 
    // 1. allocate new node
    struct Node* new_node
        = (struct Node*)malloc(sizeof(struct Node));
 
    // 2. put in the data
    new_node->data = new_data;
 
    // 3. Make next of new node as next of prev_node
    new_node->next = prev_node->next;
 
    // 4. Make the next of prev_node as new_node
    prev_node->next = new_node;
 
    // 5. Make prev_node as previous of new_node
    new_node->prev = prev_node;
 
    // 6. Change previous of new_node's next node
    if (new_node->next != NULL)
        new_node->next->prev = new_node;
}


              

C++

Java

Python3

C#

Javascript

时间复杂度: O(1)
辅助空间: O(1)

在双向链表中的给定节点之前添加一个节点:  

令指向该给定节点的指针为 next_node 这可以通过以下 6 个步骤来完成。 

  1. 为新节点分配内存,命名为 new_node
  2. 将数据放入 new_node 中。
  3. 将这个new_node 的前一个指针设置为 next_node 的前一个节点
  4. 将next_node 的前一个指针设置 new_node
  5. 将这个new_node 的下一个指针设置 next_node
  6. 现在设置new_node 的前一个指针
    • 如果 new_node 的前一个节点不为 NULL,则将该前一个节点的下一个指针设置为 new_node
    • 否则,如果 new_node 的 prev 为 NULL,则它将成为新的头节点。

插图:

请参见下图,其中“ B ”被插入到“ C ”之前。

下面是上述方法的实现。

C

// Given a node as prev_node, insert a new node
// after the given node
void insertBefore(struct Node* next_node, int new_data)
{
    // Check if the given next_node is NULL
    if (next_node == NULL) {
        printf("the given next node cannot be NULL");
        return;
    }
 
    // 1. Allocate new node
    struct Node* new_node
        = (struct Node*)malloc(sizeof(struct Node));
 
    // 2. Put in the data
    new_node->data = new_data;
 
    // 3. Make previous of new node as previous of next_node
    new_node->prev = next_node->prev;
 
    // 4. Make the previous of next_node as new_node
    next_node->prev = new_node;
 
    // 5. Make next_node as next of new_node
    new_node->next = next_node;
 
    // 6. Change next of new_node's previous node
    if (new_node->prev != NULL)
        new_node->prev->next = new_node;
    else
        head = new_node;
}


              

C++

Java

Python3

C#

Javascript

时间复杂度: O(1)
辅助空间: O(1)

在双向链表的末尾添加一个节点:

新节点始终添加在给定链表的最后一个节点之后。 这可以通过以下 7 个步骤来完成:

  1. 创建一个新节点(例如 new_node )。
  2. 将值放入新节点。
  3. 将new_node 的next指针设置 为null。
  4. 如果链表为空,则将 new_node 作为头。
  5. 否则,移动到链表的末尾。
  6. 现在使最后一个节点的下一个指针指向 new_node
  7. 将new_node 的前一个指针更改 为链表的最后一个节点。

插图:

请参见下图,其中“ D ”被插入到链表的末尾。

dll_add_end

下面是在链表末尾插入节点的7个步骤的实现:

C

// Given a reference (pointer to pointer) to the head
// of a DLL and an int, appends a new node at the end
void append(struct Node** head_ref, int new_data)
{
    // 1. allocate node
    struct Node* new_node
        = (struct Node*)malloc(sizeof(struct Node));
 
    struct Node* last = *head_ref; /* used in step 5*/
 
    // 2. put in the data
    new_node->data = new_data;
 
    // 3. This new node is going to be the last node, so
    // make next of it as NULL
    new_node->next = NULL;
 
    // 4. If the Linked List is empty, then make the new
    // node as head
    if (*head_ref == NULL) {
        new_node->prev = NULL;
        *head_ref = new_node;
        return;
    }
 
    // 5. Else traverse till the last node
    while (last->next != NULL)
        last = last->next;
 
    // 6. Change the next of last node
    last->next = new_node;
 
    // 7. Make last node as previous of new node
    new_node->prev = last;
 
    return;
}


              

C++

Java

Python3

C#

Javascript

时间复杂度: O(n)
辅助空间: O(1)

无论你的目标是考试成功、职业发展,还是纯粹的兴趣,这个数据结构和算法可视化的网站都会是一个无价的资源。

前往这个网站,开始你的学习之旅吧!

这些是常见的:【C语言描述】《数据结构和算法》数据结构JAVA实现 数据结构与算法基础(青岛大学-王卓)数据结构与算法王道数据结构c语言实现 速成数据结构期末考前救急 数据结构视频C语言版教程 数据结构严蔚敏 数据结构郝斌 数据结构考研 JAVA数据结构算法与基础 数据结构王道 2022数据结构学习 数据结构小甲鱼 王卓 学习数据结构 数据结构浙江大学 数据结构复习 数据结构马士兵 数据结构零基础教程 数据结构和算法 数据结构入门 考研数据结构习题讲解 数据结构期末复习 计算机二级