博客 / 詳情

返回

C中單向鏈表之增刪改查

C中單向鏈表之增刪改查

// 鏈表(Linked List)是一種基礎但至關重要的數據結構。它通過動態內存分配實現數據的非連續存儲,解決了數組的固定長度和插入/刪除低效的問題。無論是算法面試還是實際開發,鏈表都是高頻考點和核心技能之一。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
using namespace std;

// 單向鏈表(Singly Linked List)
typedef struct Node
{

    int num;
    char data[20];
    struct Node *next;
    Node(int x) : num(num), next(nullptr) {}
    Node() {}
} STU, Node, *PNode;
// 鏈表創建(頭插法)

PNode linked_create_head1()
{

    int num, i = 0;
    cout << "請輸入節點數量:" << endl;
    cin >> num;
    PNode head = NULL;
    PNode current = NULL;

    while (i < num)
    {
        PNode temp;
        PNode node = (PNode)malloc(sizeof(Node));
        if (node == NULL)
        {
            printf("內存分配失敗!\n");
            exit(1);
        }

        memset(node, 0, sizeof(Node));
        cout << "請輸入第" << i << "節點data:" << endl;
        cin >> node->data;

        // 如果當前頭節點為空,則將新節點作為頭節點
        if (head == NULL)
        {

            head = node;
        }
        else
        {

            node->next = head; // 將新節點的指針域指向head(老節點)

            head = node; // 將新節點作為頭節點
        }
        i++;
    }
    // 給節點編號
    current = head;
    for (int i = 0; i < num; i++)
    {
        current->num = i;
        current = current->next;
    }

    return head;
}

// 鏈表創建(尾插法)
PNode linked_create_tail()
{
    int num;
    cout << "請輸入節點數量:" << endl;
    cin >> num;

    PNode head = nullptr;
    PNode tail = nullptr; // 記錄尾節點

    for (int i = 0; i < num; i++)
    {
        // 創建新節點
        PNode node = (PNode)malloc(sizeof(Node));
        if (node == NULL)
        {
            printf("內存分配失敗!\n");
            exit(1);
        }
        memset(node, 0, sizeof(Node));

        cout << "請輸入第" << i + 1 << "個節點data:" << endl;
        cin >> node->data;
        node->num = i; // 直接設置節點編號

        // 如果是第一個節點
        if (head == nullptr)
        {
            head = node;
            tail = node;
            node->next = nullptr;
        }
        else
        {
            // 將新節點連接到鏈表尾部
            tail->next = node;
            tail = node; // 更新尾節點
            node->next = nullptr;
        }
    }

    return head;
}

// 釋放鏈表
void free_list(PNode head)
{
    // 內存釋放函數
    // 當前節點指針
    if (head == NULL)
    {
        cout << "鏈表為空" << endl;
        return;
    }
    while (head != NULL)
    {                      // 遍歷鏈表
        PNode temp = head; // 臨時保存當前節點
        head = head->next; // 移動到下一個節點
        free(temp);        // 釋放原節點內存
    }
}

void print_list(PNode *head)
{

    // 檢查鏈表是否為空
    if (*head == NULL)
    {
        printf("鏈表為空\n");
        return;
    }
    PNode current = *head; // 使用臨時變量避免修改傳入的 head 指針
    // 遍歷整個鏈表,包括最後一個節點
    while (current) // 修改為 head 而不是 head->next
    {
        printf("當前節點為:%d,節點數據為%s\n", current->num, current->data);
        current = current->next;
    }
}

/*
task     : 1.從指定位置插入節點
           2.創建一個有序鏈表,根據value值排序
*/
void update_data(PNode head, int value)
{
    PNode temp = head;
    while (temp)
    {
        if (value == temp->num)
        {
            // 找到指定節點
            // 先清空原始數據
            memset(temp->data, 0, sizeof(temp->data));
            cout << "請輸入要更改的節點數據:" << endl;
            cin >> temp->data;
            cout << "節點數據更新成功" << endl;
            printf("更改後的數據為%s\n", temp->data);
            return;
        }

        temp = temp->next;
    }
}
void insert_node(PNode head)
{
    PNode temp = head;

    PNode new_node = (PNode)malloc(sizeof(Node));
    if (new_node == NULL)
    {
        printf("內存分配失敗!\n");
        exit(1);
    }
    memset(new_node, 0, sizeof(Node));
    cout << "請輸入插入節點的序號" << endl;
    cin >> new_node->num;
    cout << "請輸入插入節點的數據" << endl;
    cin >> new_node->data;
    while (temp)
    {

        if (temp->num >= new_node->num)
        {
            if (temp->num == new_node->num)
            {
                new_node->next = temp; // 調整後續鏈表
            }
            temp->num = temp->num + 1; // 節點序號遞增
        }

        temp = temp->next;
    }
    //設置前一位node的next為new_node
    temp = head;
    while (temp)
    {
        if ((temp->num) + 1 == new_node->num)
        {
            temp->next = new_node;
            break; // 遍歷鏈表找到插入的位置
        }
    }
}

int main()
{
    PNode head;
    head = linked_create_head1();
    print_list(&head);
    insert_node(head);
    print_list(&head);
    update_data(head, 1);
    print_list(&head);
    free_list(head);
    return 0;
}

關於insert節點理解:

image-20251112213342639

我們這裏要想插入一個節點就得先找到它的序號前一位和後一位,所以我們將前一位node的next指向new_node,將new_node的next指向後一位node,將後幾位node的序號各加一

本篇用於記錄學習,如有問題歡迎指出

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.