連結串列插入

Harshit Jindal 2023年1月30日 2021年3月21日
  1. 連結串列插入演算法
  2. 連結串列插入圖
  3. 連結串列插入實現
  4. 連結串列插入演算法的複雜度
連結串列插入

在本文中,我們將學習如何在連結串列中插入節點。我們可以看到出現了 4 種不同的情況。

  1. 我們要在連結列表的開頭之前插入一個節點。此操作類似於堆疊中的推入操作。
  2. 我們要在連結列表的末尾(即尾節點旁邊)插入一個節點。
  3. 我們想在連結列表的第 i 個位置插入一個節點。
  4. 我們有該節點的引用,之後我們要插入新節點。

連結串列插入演算法

head 為指向連結串列第一個節點的指標,令 x 為要插入連結串列中的資料。

在連結列表 push() 的開頭插入節點

  • 用資料 x 建立一個新節點 temp
  • temp->next 設定為 head,以在 head 之前插入 temp
  • temp 設定為連結列表的開頭。

在連結列表 append() 的末尾插入節點

  • 用資料 x 建立一個新節點 temp
  • 初始化指向 headtail
  • 如果連結列表為空,則將 temp 設定為連結列表的 head,然後返回。
  • 否則,迭代連結列表的末尾,使 tail->next!=NULL,以便你到達最後一個元素
  • tail->next 設定為 temp

在連結列表 insertNpos()i-th 位置處插入節點

  • 如果位置 pos<=0,則返回;否則返回 0。
  • 如果 pos==0 並且 head 為空,則建立一個資料為 x 的新節點並將其設定為 head
  • 如果 pos==1,則呼叫 push()
  • 另外,用資料 x 建立一個新節點 temp
  • 初始化指向 headcurr
  • pos-- 時,執行以下操作。
    • 如果 pos==1

      • 如果 curr 不是 NULL
        • temp->next 設定為 curr->next,以便在 curr 之後插入 temp
        • curr->next 設定為 temp,以將 curr 連線到 temp
      • 返回;
    • 否則將 curr 設定為 curr->next

在給定節點的引用旁邊插入節點 - insertAfter()

  • 如果 prev==NULL,則返回;
  • 用資料 x 建立一個新節點 curr
  • curr->next 指向 prev->next 以在 prev 之後新增新節點。
  • prev->next 指向 curr 以完成插入。

連結串列插入圖

假設我們有一個節點 temp,其資料值等於 5,我們想將其插入連結串列中。讓我們考慮所有 4 種情況,並說明上述演算法是如何工作的。

在連結列表的開頭插入節點 - push()

  • temp 的指標設定為 head
  • head 指向 temp

在連結列表的開頭插入節點

在連結列表 append() 的末尾插入節點

  • curr 指向 head,資料為 2
  • curr 設定為 curr->next,並將其移動到資料為 3 的節點。
  • curr 設定為 curr->next,並將其移動到資料為 4 的節點。
  • 退出 while 迴圈並將 curr->next 設定為 temp

在連結列表的末尾插入節點

在連結列表的 i-th 位置處插入節點 - insertNpos()

我們將節點插入到位置 3

  • curr 指向 head,資料為 1pos=pos-1=2
  • curr 設定為 curr->next,並將其移動到資料為 3pos=pos -1=1 的節點。
  • temp->next 設定為 curr->next,以便在 curr 之後插入 temp。
  • curr->next 設定為 temp,以在 currcurr->next 之間完成 temp 的插入。

在連結列表的特定位置插入節點

在給定節點 insertAfter() 的引用旁邊插入節點

  • temp->next 設定為 prev->next,以在 prevprev->next 之間插入 temp
  • prev->next 設定為 temp 以完成插入。

在給定節點的引用旁邊插入節點

連結串列插入實現

#include <bits/stdc++.h>
using namespace std;

class Node {
    public:
        int data;
        Node* next;
        Node(int x) {
            this->data = x;
            this->next = NULL;
        }
};

void push(Node** head, int x)
{
    Node* temp = new Node(x);
    temp->next = (*head);
    (*head) = temp;
}

void insertAfter(Node* prev, int x)
{
    if (prev == NULL) {
        return;
    }
    Node* curr = new Node(x);
    curr->next = prev->next;
    prev->next = curr;
}

void printList(Node* head)
{
    Node*curr = head;
    while (curr != NULL) {
        cout << curr->data << " ";
        curr = curr->next;
    }
}
void insertNpos(Node**head, int x, int pos) {
    if (pos <= 0) {
        return;
    }
    if (!head && pos == 1) {
        *head = new Node(x);
    }
    else if (pos == 1) {
        push(head, x);
    }
    Node* temp = new Node(x);
    Node*curr = *head;
    while (pos--) {
        if (pos == 1) {
            if (curr) {
                temp->next = curr->next;
                curr->next = temp;
            }
            return;
        }
        curr = curr->next;
    }
}
void append(Node** head, int x)
{
    Node* temp = new Node(x);
    Node *tail = *head;
    if (*head == NULL)
    {
        *head = temp;
        return;
    }
    while (tail->next != NULL)
        tail = tail->next;
    tail->next = temp;
    return;
}

int main()
{
    Node* head = new Node(1);
    head -> next = new Node(2);
    printList(head); cout << "\n";
    push(&head, 3);
    push(&head, 4);
    printList(head); cout << "\n";
    append(&head, 5);
    printList(head); cout << "\n";
    insertAfter(head->next->next, 6);
    printList(head); cout << "\n";
    insertNpos(&head, 24, 2);
    printList(head);
    return 0;
}

連結串列插入演算法的複雜度

時間複雜度

  • 平均情況

要將節點插入連結串列中的第 i 個位置,我們必須訪問 i 個節點。因此,時間複雜度約為 O(i)。而且我們在連結串列中有 n 個節點,因此平均情況下的時間複雜度為 O(n/2)O(n)。時間複雜度約為 O(n)

  • 最佳情況

最好的情況是,當我們想在連結串列的開頭插入一個節點,或者在插入站點之前有對該節點的引用時。最佳情況下的時間複雜度是 O(1)

  • 最壞情況

最差的時間複雜度是 O(n)。這與平均情況下的時間複雜度相同。

空間複雜度

該插入演算法的空間複雜度為 O(1),因為除 curr 指標外不需要其他空間。

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

相關文章 - Data Structure

相關文章 - Linked List