不带头结点的单链表------C语言实现

article/2025/11/9 6:44:36
  1 /****************************************************/  3 File name:no_head_link.c4 Author:SimonKly   Version:0.1    Date: 2017.5.205 Description:不带头节点的单链表6 Funcion List: 7 *****************************************************/8 9 #include <stdio.h>10 #include <stdlib.h>11 12 typedef struct node13 {14     int id;15     struct node * next;16 }* Link, Node;17 18 /*创建链表*/19 void create_link(Link * head)20 {21     *head = NULL;//空链表22 }23 24 /*头插*/25 void insert_node_head(Link * head, Link new_node)26 {27     new_node->next = *head;28     *head = new_node;29 }30 31 #if 132 /*尾插*/33 void insert_node_tail(Link * head, Link new_node)34 {35     Link p = NULL;36 37     if (*head == NULL)38     {39         *head =new_node;40         new_node->next = NULL;41         return ;42     }43     else44     {45         p = *head;46         while (p->next != NULL)47         {48             p = p->next;49         }50         p->next = new_node;51         new_node->next = NULL;52     }53 }54 #endif55 56 /*输出链表*/57 void display_link(Link head)58 {59     Link p = NULL;60 61     p = head;62 63     if(p == NULL)64     {65         printf("link is empty!\n");66         return ;67     }68 69     while (p != NULL)70     {71         printf("id = %d\n", p->id);72         p = p->next;73     }74 75     putchar(10);76 }77 78 /*检查malloc是否分配成功*/79 void is_malloc_ok(Link new_node)80 {81     if (new_node == NULL)82     {83         printf("malloc error!\n");84         exit(-1);85     }86 }87 88 /*创建节点*/89 void create_node(Link * new_node)90 {91     *new_node = (Link)malloc(sizeof(Node));92 93     is_malloc_ok(*new_node);94 }95 96 /*释放节点*/97 void realse_node(Link * head)98 {99     Link p = NULL;
100 
101     p = *head;
102     while (*head != NULL)
103     {
104         *head = (*head)->next;//head移动
105         free(p);//释放head之前的节点
106         p = *head;
107     }
108 }
109 
110 
111 /*中间插入节点*/
112 void insert_node_mid(Link * head, Link new_node, int loc)
113 {
114     int i;
115     Link p = NULL;
116 
117     p = *head;
118 
119     for(i = 1; i < loc; i++)
120     {
121         p = p->next;
122     }
123 
124     new_node->next = p->next;
125     p->next = new_node;
126 }
127 
128 /*中间插入,前面*/
129 void insert_node_mid_front(Link * head, Link new_node)
130 {
131     Link p = NULL, q = NULL;
132 
133     p = q = *head;
134 
135     if (*head == NULL)
136     {
137         printf("link is empty\n");
138         return ;
139     }
140 
141     while (p != NULL && p->id != new_node->id)
142     {
143         q = p;
144         p = p->next;
145     }
146     
147     if (p == NULL)
148     {
149         printf("No such node in link!\n");
150         free(new_node);
151         return ;
152     }
153     if (p->id == (*head)->id)
154     {
155         new_node->next = *head;
156         *head = new_node;
157     }
158     else
159     {
160         q->next = new_node;
161         new_node->next = p;
162     }
163 }
164 #if 1
165 /*删除节点*/
166 void delete_node(Link * head, int data)
167 {
168     Link p = NULL, q = NULL;
169 
170     q = p = *head;
171 
172     if (p == NULL)//链表为空的时候
173     {
174         printf("link is empty!\n");
175         return ;
176     }
177     else//链表不为空的时候
178     {
179         while (p != NULL && p->id != data)//寻找节点
180         {
181             q = p;
182             p = p->next;
183         }
184 
185         if ((*head)->id == data)//删除节点为头节点时
186         {
187             *head = (*head)->next;
188             free(p);//free(q);
189         }
190         else//删除节点不为头节点,尾节点不用考虑
191         {
192             q->next = p->next;
193             free(p);
194         }
195     }
196 }
197 #endif
198 
199 #if 0
200 void delete_node(Link * head, int data)
201 {
202     Link p = NULL, q = NULL;
203 
204     q = p = *head;
205 
206     if (p == NULL)//链表为空的时候
207     {
208         printf("link is empty!\n");
209         return ;
210     }
211     else//链表不为空的时候
212     {
213         while (p != NULL && (p->next)->id != data)//寻找节点
214         {
215             p = p->next;
216         }
217 
218         if ((*head)->id == data)//删除节点为头节点时
219         {
220             *head = (*head)->next;
221             free(p);//free(q);
222         }
223         else//删除节点不为头节点,尾节点不用考虑
224         {
225             q = p->next;
226             p->next = q->next;
227             free(q);
228         }
229     }
230 }
231 #endif
232 
233 /*插入之后依旧有序*/
234 void insert_node_seq(Link * head, Link new_node)
235 {
236     Link p = NULL, q = NULL;
237 
238     p = q = *head;
239 
240     if (p == NULL)//链表为空的时候
241     {
242         *head = new_node;
243         new_node->next = NULL;
244     }
245     else
246     {
247         while (p != NULL && p->id < new_node->id)//寻找位置
248         {
249             q = p;
250             p = p->next;
251         }
252         
253         if ((*head)->id > new_node->id)//找到的节点为头节点
254         {
255             new_node->next = *head;
256             *head = new_node;
257         }
258         else
259         {
260             q->next = new_node;
261             new_node->next = p;
262         }
263     }
264 }
265 
266 #if 1
267 /*插入依旧有序实现方法二*/
268 void insert_node_seq_1(Link * head, Link new_node)
269 {
270     Link p = NULL;
271     Link q = NULL;
272 
273     p = q = *head;
274 
275     if (p == NULL)//空链表
276     {
277         *head = new_node;
278         new_node->next =NULL;
279     }
280     else
281     {
282         while ((p->id < new_node->id) && (p->next != NULL))
283         {
284             q = p;
285             p = p->next;
286         }
287         
288         if ((*head)->next == NULL)//一个节点的时候
289         {
290             if (p->id > new_node->id)
291             {
292                 new_node->next = *head;
293                 *head = new_node;
294             }
295             else
296             {
297                 p->next = new_node;
298             }
299         }
300         else
301         {
302             if (p->next == NULL)//尾节点
303             {
304                 if (p->id > new_node->id)//插入前
305                 {
306                     q->next = new_node;
307                     new_node->next = p;
308                 }
309                 else
310                 {
311                     p->next = new_node;
312                 }
313             }
314             else//不是尾节点
315             {
316                 if((*head)->id > new_node->id)//头节点
317                 {
318                     new_node->next = *head;
319                     *head = new_node;
320                 }
321                 else//中间插入时
322                 {
323                     q->next = new_node;
324                     new_node->next = p;
325                 }
326             }
327         }/*end of if()*/
328     }/*end of if (p == NULL)*/
329 }
330 #endif
331 
332 int main()
333 {
334     Link head = NULL;//防止出现野指针
335     Link new_node = NULL;//防止出现野指针
336     int i;
337     int data;
338 
339     create_link(&head);//创建链表
340 
341     for (i = 0; i < 10; i++)//值域赋值,并插入新节点
342     {
343     //    new_node = (Link)malloc(sizeof(Node));//创建新节点
344         create_node(&new_node);
345     //    new_node->id = i + 1;//赋值
346     //    insert_node_head(&head, new_node);//插入节点,头插
347     //    insert_node_tail(&head, new_node);//插入节点,尾插
348     
349         printf("please input node value:\n");
350         scanf("%d", &new_node->id);
351         insert_node_seq(&head, new_node);
352 //        insert_node_seq_1(&head, new_node);
353         display_link(head);//输出节点的值域
354     }
355 
356     display_link(head);//输出节点的值域
357 
358 #if 0
359     create_node(&new_node);
360     new_node->id = i + 1;
361     insert_node_mid(&head, new_node, 3);//指定位置插入,中间插入
362     putchar(10);
363     display_link(head);//输出节点的值域
364 
365 #if 0
366     create_node(&new_node);
367     scanf("%d", &new_node->id);
368     insert_node_mid_front(&head, new_node);
369     display_link(head);//输出节点的值域
370 #endif
371 
372     scanf("%d", &i);
373     delete_node(&head, i);//删除指定节点
374     display_link(head);
375 
376 #if 0
377 
378     create_node(&new_node);
379     scanf("%d", &new_node->id);
380     insert_node_seq(&head, new_node);//有序插入指定元素
381     display_link(head);
382 #endif
383 #endif
384     realse_node(&head);//释放节点
385 
386     display_link(head);//输出节点的值域
387     return 0;
388 }

复制代码

由于链式数据结构中有指针的各种指向问题,所以在纸上画图是比较容易理解。

其中在对头指针(注意是头指针,不是头节点,两个不是一个概念,头指针是整个链表的操作的基础,链表存在的象征,头指针是整个“链表公司”的一把手,头头结点是链表中的第一个元素)的操作,除了在插入,删除和销毁中头指针的指向发生改变,需要直接对头指针head操作外,其他方法都不要对头指针进行操作,以免丢失整个链表。

在对链表中的增加时,需要考虑链表中开始存在的元老级的“人物”,所以我们不能随便就对它们变换“岗位”,我得先找到”接班人“之后再对这些元老级的岗位进行调整。

在对链表中的节点进行删除时,也需要首先考虑这些元老级的“人物”,毕竟人家没有功劳也有苦劳,我们得代理好它走后它的”上级“和他的”下级“沟通交流的问题。

代码中的一些条件编译和注释是未完成一些功能的另一种方法。

在销毁整个链表时,相当于整个链表公司破产,作为公司一把手的head,依次需要对手下任劳任怨的员工进行思想工作。当整个公司没有员工时,一把手也什么都没有了即NULL。

代码中的功能函数包括:

1.创建链表

2.创建节点

3.插入节点------------头插,尾插以及插入即有序,指定位置插入的方法,根据需要选择合适的方法

  头插:实现链式栈

  尾插:实现链式队列

4.删除节点

5.销毁整个链

6.判断malloc函数是否执行成功

7.输出链

来源:http://www.cnblogs.com/SimonKly/p/6890287.html


http://chatgpt.dhexx.cn/article/1VEFNY1K.shtml

相关文章

单链表的头结点的作用

问题&#xff1a;在单链表中使用“头结点”&#xff0c;这个哑结点始终是链表的第一个元素&#xff0c;这个技巧的利与弊&#xff1f; 链表中第一个结点的存储位置叫做头指针&#xff0c;那么整个链表的存取就必须从头指针开始进行了。之后的每一个结点&#xff0c;其实就是上…

【数据结构】单链表之带头结点的单链表

一、单链表相关知识点介绍&#xff1a; 1. 结点&#xff1a;结点就是单链表中研究的数据元素&#xff0c;结点中存储数据的部分称为数据域&#xff0c;存储直接后继地址的部分称为指针域。 2. 头结点&#xff1a;引入头结点的目的是&#xff0c;将链表首元结点的插入和删除操作…

【链表】带头节点和不带头节点单链表的区别

目录 &#x1f354;当链表的结点只包含一个指针域时&#xff0c;叫做单链表 &#x1f354;不论带不带头节点&#xff0c;所有的链表都要有个头指针&#xff01; &#x1f35f;带头结点的链表的头指针指向的是头结点&#xff0c;头结点的指针域指向首元结点 &#x1f35f;不带…

带头结点的单链表的操作(C语言)

初始化 先了解头结点 头结点是一个特殊的结点&#xff0c;它的数据域不存储信息&#xff0c;通常情况下&#xff0c;头指针指向的结点为头结点&#xff0c;由于头结点不存储信息&#xff0c;所以不是数据结构中的实际结点&#xff0c;第一个实际结点其实是head->next指示的…

单链表(不带头结点)

单链表不带头结点结构体设计&#xff1a; //不带头结点的结构体设计&#xff1a; typedef int ELEM_TYPE;//有效数据节点结构体设计 typedef struct Node {ELEM_TYPE data;//数据域 &#xff08;1.头结点&#xff1a;不保存任何数据 2.有效数据节点&#xff1a;保存有效值…

数据结构之不带头结点的单链表

我们都知道不管是单链表、双向链表还是循环链表&#xff0c;都带有头结点&#xff0c;这个头结点相当于一个起始的位置。我们在设计带头结点的单链表的时候&#xff0c;我们会在主函数中设计一个头结点&#xff0c;并把它的指针域置为空&#xff0c;这样我们就可以进行增删查改…

数据结构--带头结点的单链表

单链表分为&#xff1a;带头结点和不带头结点&#xff0c;不带头结点的单链表需要用到二级指针&#xff0c;容易出错。 1、结构体设计 typedef int ELEM_TYPE; //有效数据节点结构体设计&#xff08;头结点借用&#xff09; typedef struct Node {ELEM_TYPE data;//数据域 &…

带头结点的单链表的总结

线性表的链式存储是用若干地址分散的存储单元存储数据元素&#xff0c;逻辑上相邻的数据元素在物理位置上不一定相邻。 带头结点的单链表是指&#xff0c;在单链表的第一个结点之前增加一个特殊的结点&#xff0c;称为头结点。 头结点的作用&#xff1a;使所有链表&#xff08;…

单链表的创建(带头结点和不带头结点)

伪代码&#xff1a; 创建结点 创建头结点(单独定义一个结构体来保存单链表的首地址和尾地址还有链表的长度) 创建带头结点的单链表 注意&#xff1a;创建头结点中的首尾指针都要指空&#xff0c;长度等于0&#xff1b; 从终端接收数据 创建结点保存数据&#xff1a; 创建的节点…

单链表———带头结点跟不带头结点的区别

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、单链表&#xff1a;带头结点跟不带头结点二、使用步骤总结 前言 数据结构中单链表的创建 带头结点跟不带头结点的区别 一、单链表&#xff1a;带头结点跟…

【数据结构】带头结点的单链表

文章目录 一、单链表的概念二、结构体声明&#xff1a;三、函数1.购买节点2.释放节点3.单链表的初始化4.判空函数5.获取单链表有效值个数6.按数据查询&#xff08;返回含有此数据节点的前驱&#xff09;7.按数据查询&#xff08;返回含有当前数据的节点&#xff09;8.按pos位置…

【考研】分清带头结点和不带头结点的单链表

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 前言 为分清带结点与不带头结点的单链表操作&#xff0c;本文以图文和表格形式描述了两者之间的区别。考研中&#xff0c;数据结构的单链表操作是重要考点&#xff0c;其中&#xff0c;比较常考带头结点的链表操作。 所以&…

【带头结点的单链表】

带头结点的单链表 前言一、带头结点的单链表结构体设计1. 带头结点的单链表2. 结构体声明 二、函数实现1. 初始化2. 申请新节点3. 头插4. 尾插5. 按位置插入6. 头删7. 尾删8. 销毁 总结 前言 单链表的概念&#xff1a; 单链表是一种链式存取的数据结构&#xff0c;用一组地址…

带头结点单链表 (详解)

单链表结构体 结构体后的*List是一个指向结构体的指针类型&#xff0c;我们通过它来定义该类型的指针。 如&#xff1a;List p ;  则这个p就是指向LinkedList结构体的一个指针&#xff0c;也就是单链表的头指针。&#xff08;所以说头指针是必然存在的&#xff0c;但单链表不…

数据结构-带头节点的单链表(C语言)超详细讲解

前面我们学到线性表的顺序存储结构&#xff08;顺序表&#xff09;&#xff0c;发现它有着明显的缺点&#xff1a;插入和删除元素时需要频繁的移动元素&#xff0c;运算效率低。必须按事先估计的最大元素个数申请连续的存储空间。存储空间估计大了&#xff0c;造成浪费空间&…

Windows配置端口转发绕过samba 445端口限制共享linux磁盘

概述 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件。SMB&#xff08;Server Messages Block&#xff0c;信息服务块&#xff09;是一种在局域网上共享文件和打印机的一种通信协议&#xff0c;它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。SMB协议…

Linux安装samba服务

个人推荐: &#x1f4e2;&#x1f4e2;&#x1f4e2; 前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下 "通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。点击跳转到教程。 一&#xff1a;使用到的Linux指令 1:检查是否…

samba服务

目录 一&#xff1a;samba概述 1.1samba简介 1.2samba的监听端口 1.3samba的进程 1.4samba安全级别 二&#xff1a;samba服务的特点 三&#xff1a;samba的主要作用 四&#xff1a;常见文件服务器软件的对比 五&#xff1a;samba配置文件 5.1samba主配置文件 5.2常用…

Samba配置详解

一、简介 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件&#xff0c;而SMB是Server Message Block的缩写&#xff0c;即为服务器消息块 &#xff0c;SMB主要是作为Microsoft的网络通讯协议&#xff0c;后来Samba将SMB通信协议应用到了Linux系统上&#xff0c;就形成…

Windows 10 下修改 smb 连接的默认端口(445)

服务器&#xff08;samba 共享文件夹所在服务器&#xff09;上已经frp外网映射445 端口转接4455 windows10 右键开始–powershell&#xff08;管理员&#xff09; netsh interface portproxy add v4tov4 listenport445 listenaddress127.0.0.1 connectport4455 connectaddress …