返回

掌握力扣的循环链表排序插入法

前端

前言

在计算机科学领域,链表是一种常见的数据结构,以其简单和灵活性而被广泛使用。循环链表是链表的一种特殊形式,其中最后一个节点指向第一个节点,形成一个环。循环链表在许多应用场景中都有着重要的作用。

循环链表的排序插入算法

在循环链表中插入一个新元素 insertVal,并保持循环升序,需要遵循一定的算法步骤。这里我们将详细介绍这一算法:

  1. 查找插入点: 首先,我们需要找到链表中合适的位置来插入新元素 insertVal。为此,我们需要遍历链表,比较每个节点的值与 insertVal 的大小关系。当我们找到第一个大于或等于 insertVal 的节点时,我们就找到了插入点。
  2. 创建新节点: 找到插入点后,我们需要创建一个新的节点来存储 insertVal。这个新节点的 next 指针应指向插入点指向的节点,而 previous 指针应指向插入点前一个节点。
  3. 更新指针: 将插入点的 next 指针指向新节点,将新节点的 previous 指针指向插入点的前一个节点。
  4. 检查循环: 最后,我们需要检查循环是否仍然完整。由于我们插入了一个新节点,我们需要确保最后一个节点的 next 指针指向第一个节点,而第一个节点的 previous 指针指向最后一个节点。如果这两个条件都满足,那么循环仍然完整。

算法的复杂度

循环链表的排序插入算法的复杂度为 O(n),其中 n 是链表的长度。这是因为我们需要遍历链表一次,找到插入点,并执行插入操作。在最坏的情况下,当插入点是最后一个节点时,我们需要遍历整个链表,因此复杂度为 O(n)。

示例代码

以下是用 C++ 实现的循环链表的排序插入算法的示例代码:

struct Node {
  int val;
  Node *next;
  Node *prev;
  Node(int val) : val(val), next(nullptr), prev(nullptr) {}
};

void insert(Node *head, int insertVal) {
  Node *newNode = new Node(insertVal);
  if (head == nullptr) {
    newNode->next = newNode;
    newNode->prev = newNode;
    return;
  }

  Node *curr = head;
  while (curr->next != head && curr->val < insertVal) {
    curr = curr->next;
  }

  newNode->next = curr->next;
  curr->next = newNode;
  newNode->prev = curr;
  newNode->next->prev = newNode;
}

结语

通过对循环链表的排序插入算法的详细介绍,我们了解了如何在循环单调非递减列表中插入一个新元素,使列表仍然保持循环升序。这一算法在许多应用场景中都有着重要的作用。希望本文能够帮助您更好地理解和掌握这一算法。