莲生女算 發表於 2025-11-12 21:49:00

C中单向链表之增删改查

<h1 id="c中单向链表之增删改查">C中单向链表之增删改查</h1>
<pre><code class="language-c">// 链表(Linked List)是一种基础但至关重要的数据结构。它通过动态内存分配实现数据的非连续存储,解决了数组的固定长度和插入/删除低效的问题。无论是算法面试还是实际开发,链表都是高频考点和核心技能之一。
#include &lt;iostream&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;cstring&gt;
using namespace std;

// 单向链表(Singly Linked List)
typedef struct Node
{

    int num;
    char data;
    struct Node *next;
    Node(int x) : num(num), next(nullptr) {}
    Node() {}
} STU, Node, *PNode;
// 链表创建(头插法)

PNode linked_create_head1()
{

    int num, i = 0;
    cout &lt;&lt; "请输入节点数量:" &lt;&lt; endl;
    cin &gt;&gt; num;
    PNode head = NULL;
    PNode current = NULL;

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

      memset(node, 0, sizeof(Node));
      cout &lt;&lt; "请输入第" &lt;&lt; i &lt;&lt; "节点data:" &lt;&lt; endl;
      cin &gt;&gt; node-&gt;data;

      // 如果当前头节点为空,则将新节点作为头节点
      if (head == NULL)
      {

            head = node;
      }
      else
      {

            node-&gt;next = head; // 将新节点的指针域指向head(老节点)

            head = node; // 将新节点作为头节点
      }
      i++;
    }
    // 给节点编号
    current = head;
    for (int i = 0; i &lt; num; i++)
    {
      current-&gt;num = i;
      current = current-&gt;next;
    }

    return head;
}

// 链表创建(尾插法)
PNode linked_create_tail()
{
    int num;
    cout &lt;&lt; "请输入节点数量:" &lt;&lt; endl;
    cin &gt;&gt; num;

    PNode head = nullptr;
    PNode tail = nullptr; // 记录尾节点

    for (int i = 0; i &lt; num; i++)
    {
      // 创建新节点
      PNode node = (PNode)malloc(sizeof(Node));
      if (node == NULL)
      {
            printf("内存分配失败!\n");
            exit(1);
      }
      memset(node, 0, sizeof(Node));

      cout &lt;&lt; "请输入第" &lt;&lt; i + 1 &lt;&lt; "个节点data:" &lt;&lt; endl;
      cin &gt;&gt; node-&gt;data;
      node-&gt;num = i; // 直接设置节点编号

      // 如果是第一个节点
      if (head == nullptr)
      {
            head = node;
            tail = node;
            node-&gt;next = nullptr;
      }
      else
      {
            // 将新节点连接到链表尾部
            tail-&gt;next = node;
            tail = node; // 更新尾节点
            node-&gt;next = nullptr;
      }
    }

    return head;
}

// 释放链表
void free_list(PNode head)
{
    // 内存释放函数
    // 当前节点指针
    if (head == NULL)
    {
      cout &lt;&lt; "链表为空" &lt;&lt; endl;
      return;
    }
    while (head != NULL)
    {                      // 遍历链表
      PNode temp = head; // 临时保存当前节点
      head = head-&gt;next; // 移动到下一个节点
      free(temp);      // 释放原节点内存
    }
}

void print_list(PNode *head)
{

    // 检查链表是否为空
    if (*head == NULL)
    {
      printf("链表为空\n");
      return;
    }
    PNode current = *head; // 使用临时变量避免修改传入的 head 指针
    // 遍历整个链表,包括最后一个节点
    while (current) // 修改为 head 而不是 head-&gt;next
    {
      printf("当前节点为:%d,节点数据为%s\n", current-&gt;num, current-&gt;data);
      current = current-&gt;next;
    }
}

/*
task   : 1.从指定位置插入节点
         2.创建一个有序链表,根据value值排序
*/
void update_data(PNode head, int value)
{
    PNode temp = head;
    while (temp)
    {
      if (value == temp-&gt;num)
      {
            // 找到指定节点
            // 先清空原始数据
            memset(temp-&gt;data, 0, sizeof(temp-&gt;data));
            cout &lt;&lt; "请输入要更改的节点数据:" &lt;&lt; endl;
            cin &gt;&gt; temp-&gt;data;
            cout &lt;&lt; "节点数据更新成功" &lt;&lt; endl;
            printf("更改后的数据为%s\n", temp-&gt;data);
            return;
      }

      temp = temp-&gt;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 &lt;&lt; "请输入插入节点的序号" &lt;&lt; endl;
    cin &gt;&gt; new_node-&gt;num;
    cout &lt;&lt; "请输入插入节点的数据" &lt;&lt; endl;
    cin &gt;&gt; new_node-&gt;data;
    while (temp)
    {

      if (temp-&gt;num &gt;= new_node-&gt;num)
      {
            if (temp-&gt;num == new_node-&gt;num)
            {
                new_node-&gt;next = temp; // 调整后续链表
            }
            temp-&gt;num = temp-&gt;num + 1; // 节点序号递增
      }

      temp = temp-&gt;next;
    }
    //设置前一位node的next为new_node
    temp = head;
    while (temp)
    {
      if ((temp-&gt;num) + 1 == new_node-&gt;num)
      {
            temp-&gt;next = new_node;
            break; // 遍历链表找到插入的位置
      }
    }
}

int main()
{
    PNode head;
    head = linked_create_head1();
    print_list(&amp;head);
    insert_node(head);
    print_list(&amp;head);
    update_data(head, 1);
    print_list(&amp;head);
    free_list(head);
    return 0;
}
</code></pre>
<p>关于insert节点理解:</p>
<p><img src="https://images.cnblogs.com/cnblogs_com/blogs/851403/galleries/2471304/o_251112134633_image-20251112213342639.png" alt="image-20251112213342639" loading="lazy"></p>
<p>我们这里要想插入一个节点就得先找到它的序号前一位和后一位,所以我们将前一位node的next指向new_node,将new_node的next指向后一位node,将后几位node的序号各加一</p>
<blockquote>
<p>本篇用于记录学习,如有问题欢迎指出</p>
</blockquote>


</div>
<div id="MySignature" role="contentinfo">
    我要吃炸鸡<br><br>
来源:https://www.cnblogs.com/Langx/p/19215596
頁: [1]
查看完整版本: C中单向链表之增删改查