单链表之头插法

article/2025/9/30 3:07:38

1、前言:

什么是头插法?说白了头插法就是新增节的点总是插在头节点后面,然后大家可能会有疑惑,什么是新增节点,什么是头节点呢,下面请听俺娓娓道来。。。

2、预前准备:

头节点:一个队伍通常需要有一个标杆,就也是站在第一排举旗的那个人,头节点就相当于那个举旗的人,它不需要存放数据,只需起到标杆的作用,下面用 L 来表示头节点。

新增节点:相当于后面的小兵,手里需要拿着装备(数据域)和用来指向下一个小兵的位置(指针域),下面用 P 来表示新增节点。

数据域:用来存放用户的数据。

指针域:用来指向下一个节点的地址注意是地址,而不是下一个节点的指针域。

p->next=p 与 p=p->next区别:p->next=p表示节点p的下一个节点还是p,如果链表只有p节点,那么这样就变成了一个循环链表
p=p->next表示修改指针p的位置,把p指向原来的下一个节点。

头插法的插入过程:

A

那么怎么实现呢?

3、实现过程

首先需要创建一个头节点,用来当标杆。

L = (LiskList)malloc(sizeof(LNode)) 

目的是在计算机内存中开辟一块LNode大小的空间,用来存放数据与指针。在Java 或 C++中就是 L = new LNode

最开始头节点的指针域不指向任何节点P(也就是指向NULL),即 L->next = NULL,数据域不存放任何数据,如图

开辟一块用来存放数据的节点P

P = (LiskList)malloc(sizeof(LNode))

当有元素插入时,将头节点的指针域放到新节点P后(P的指针域),如图:

P -> data = an
P -> next = L -> next //这里的 L->next是指头节点后面的所有节点,所以不能用 P->next = NULL来替代

然后将新节点P放在头节点后面,怎么接呢?

这么接,将新节点的地址赋值给头节点的指针域

L-> next = p

这样就完成了第一个节点的插入,之后节点的插入都是这样,为了看得更明显,咱们再接着插入第二个节点,怎么插呢?

同理在开辟一块内存空间用来存放数据,为了方便,这块空间的名字还叫P。

P = (LiskList)malloc(sizeof(LNode))

将 an-1 放在新开辟节点P的数据域中。

P -> data = an-1

现在链表的情况如图,头节点与an所在的节点相连着,an-1所在的节点还未连接。

然后我们将头节点后面所有的节点(目前只有an所在的节点)都接在新增节点P(an-1所在的节点)的后面。

并且因为an所在的节点的地址存放在L->next中,所以只需将L->next的值赋给P->next,这样便把an节点接到了an-1的后面

P->next = L->next

最后还需要将P节点插入到头节点的后面,之后循环如此这样便实现了头插过程。

L->next = P

 

4、代码实现:

//头插法创建单链表
LNode* List_HeadCreate(LNode* L,int a[],int n){LNode *s;//新增节点L = (LNode*)malloc(sizeof(LNode)); //为L开辟一处空间,或者在主函数中开辟也可以L->next = NULL;for(int i=0;i<n;i++){s = (LNode*)malloc(sizeof(LNode));s->data = a[i];//将新增节点存放上数据s->next = L->next;//连接s的后继L->next = s;//连接s的前驱}return L;
}

如果创建懂了那么插入、删除操作也就理解了。

5、完整代码:

#include<stdio.h>
#include <stdlib.h>
//define a struct 
//定义一个结构体,也就是节点
typedef struct Node {int data;                    // 存储链表数据struct Node *next;     		//  存储结点的地址
}LNode,*LinkList;//头插法创建单链表
LNode* List_HeadCreate(LNode* L,int a[],int n){LNode *s;//新增节点L = (LNode*)malloc(sizeof(LNode)); //为L开辟一处空间,或者在主函数中开辟也可以L->next = NULL;for(int i=0;i<n;i++){s = (LNode*)malloc(sizeof(LNode));s->data = a[i];//将新增节点存放上数据s->next = L->next;//连接s的后继L->next = s;//连接s的前驱}return L;
}//头插法插入元素
LNode* List_HeadInsert(LNode* head,int i,int num){ //插入元素到第i个位置,插入数numLNode *P;LNode *Q;P = head;//创建临时头节点int j = 0;while(j<i-1 && P!=NULL){  //寻找插入位置的前驱节点P =  P->next;j++;}if(j == i-1 && P!=NULL){  //头插法插入Q = (LNode*)malloc(sizeof(LNode));//创建将要插入的节点Q->data = num;Q->next = P->next;//第一步,连接Q的后继P->next = Q;//第二步,连接Q的前驱}return head;//返回链表首地址
}//头插法删除指定位置元素
LNode* List_HeadDelete(LNode* L,int i) //删除第i个位置元素
{LNode* P;LNode* Q;P = L;int j=0;while (j<i-1 && P){/* code */P = P->next;j++;}if(j == i-1 && P){Q = P->next;P->next = P->next->next;free(Q);}return L;
}//主函数,给链表赋值并打印出链表
void main(){int arr[] = {1,2,3,4,5};int n = 5;LNode *L = NULL;L = List_HeadCreate(L,arr,sizeof(arr)/sizeof(arr[0]));L = List_HeadInsert(L,3,500);L = List_HeadDelete(L,6);while(L->next!=NULL){printf(" %d ",L->next->data);//算上头节点一共六个节点,并且头节点数据域为NULL,所以输出的第一个值应该为 L->next->dataL = L->next;}
}

 

其中:

LNode *和 LinkList是等价的,只是要注意下面这样的变量声明:
LinkList P,Q; /*P,Q都是指针*/
LNode *P,Q;/*只有P是指针*/

6、、指针和引用的区别?

1、本质区别

本质: 指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名,引用不改变指向

2、指针和引用作为函数参数进行传递时的区别
(1)指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
(2)引用传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

 

看没看懂都点个赞呗 ~~~


http://chatgpt.dhexx.cn/article/xVgUkDn0.shtml

相关文章

单链表的头插法和尾插法的示例

单链表是数据结构中最基本的数据结构&#xff0c;单链表有头插法和尾插法&#xff0c;今天有空把这两者做成一个实验示例以作比较。 提示&#xff1a;编译代码是否通过可能与编译器的版本有关&#xff0c;本程序是在 Android 操作系统下的 Compiler C语言编译器下编译通过。 一…

头插法实现单链表逆置

在头结点的后面依次插入后面的结点&#xff0c;q从第二个结点向后移动遍历&#xff0c;p永远在第一个结点完成头插法逆置单链表。 void reverseL(Linklist &L){//头插法逆转单链表if(L!NULL){LNode* pL->next;//p等于第一个结点LNode* qp->next;//q等于第二个结点p-…

HashMap/ConcurrentHashMap/头插法/尾插法

1.1 HashMap JDK1.7 JDK1.8 存储 数组链表 数组链表红黑树 位置算法 h & (length-1) h & (length-1) 链表超过8 链表 红黑对(链表超过8且数组长度超64) 节点结构 Entry<K,V> implements Map.Entry<K,V> Node<K,V> implements Map.Entry…

C语言 链表 头插法

代码&#xff08;VS2017中运行&#xff09; #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct student {int num;float score;struct student *pnext;//*pnext存的是下一个节点的首地址 }stu,*pst…

头插法建立单链表

头插法建立单链表图示过程&#xff08;其中an表示时间上第n个建立的节点&#xff0c;L为头指针&#xff0c;箭头表指向&#xff0c;sn代表an的地址&#xff09; 结构体代码与主函数如下&#xff1a; struct Link //创建一个结构体类型 {int data; //数据域struct Link* p; /…

Java实现头插法

实现原理&#xff1a; 这是第一个头结点&#xff0c;现在要插入一个节点&#xff0c;也就是让新节点指向该头结点&#xff0c;任何让head指向新节点&#xff0c;新节点变为头结点。 代码实现&#xff1a; 实体类&#xff1a; public class entity {private String data;privat…

单链表的头插法

链表与顺序表不同链表是用一组任意的储存单元来存放线性表的结点&#xff0c;这组结点可以是连续的&#xff0c;也可以是非连续的&#xff0c;甚至可以是零散分布在内存的任何位置&#xff0c;为了能正确的去表达结点的逻辑关系&#xff0c;必须在储存元素值的同时&#xff0c;…

HashMap在JDK1.7版本头插法实现解析

HashMap在JDK1.7版本头插法实现解析 先解释下何为头插法。大家都知道HashMap在JDK1.7版本的数据结构为数组链表这样的形式。而头插法说的就是在往HashMap里面put元素时&#xff0c;此时新增在链表上元素的位置为链表头部&#xff0c;也就是数组桶位上的那个位置&#xff0c;故…

头插法链表反转c语言,用头插法反转链表

题目&#xff1a;输入一个链表的头结点&#xff0c;反转该链表&#xff0c;并返回反转后链表的头结点。 链表结点定义如下&#xff1a; typedef char item_t; typedef struct node { item_t item; struct node * next; } node_t; 分析&#xff1a; 使用头插法可以快速实现反转。…

链表头插法

头插法 从一个空表头指针开始&#xff0c;重复读入数据&#xff0c;生成新节点&#xff0c; 将读入数据存放到新节点的数据域中&#xff0c;永远是将新节点插入到当前链表的头节点的后面&#xff0c;第一个创建的节点是放在最后的&#xff0c;直到读入结束标志才停止创建。 #in…

HashMap头插法

HashMap在1.8&#xff08;不含&#xff09;之前对于新增元素的hash冲突的链表插入采用的是头插法&#xff0c;1.8之后开始改用尾插法。那么头插法有什么问题呢&#xff1f;为什么改用尾插法呢&#xff1f;源码学习一下咯 HashMap-jdk1.7.0_80 put新增map元素 public V put(K…

(最详细)c语言尾插法头插法代码讲解

1.尾插法 尾插法 头指针和尾指针都指向头结点&#xff0c;然后往里边插入元素&#xff0c; 每插入一个元素尾指针就后移一下 其中如下图所示 尾插法的核心代码是&#xff1a; pointer->next s; //pointer指向新生成的节点 pointer pointer->next;//pointer移动至新…

头插法和尾插法总结(动图版)

代码使用结构体&#xff1a; typedef struct Node{int value;struct Node* next; }*Link;头插法&#xff1a;利用头指针控制链表节点的增加。 核心&#xff1a; newNode->next head->next; head->next newNode; //头插法创建链表 Link headCreateLink(int n){//头指…

头插法和尾插法建立单链表详解与实现

写在前面&#xff1a;本文使用C语言和C引用&#xff0c;学C和C的同学都是可以看懂的&#xff0c;C毕竟向下兼容C。很详细&#xff0c;一篇能搞懂代码和原理。 先来了解几个简单概念 单链表就是线性表的链式存储&#xff1b; 头结点&#xff1a;单链表在第一个结点之前附加了一个…

链表的三种插入方法(头插法,尾插法,任意位置插入)

插入作为链表的四大基本操作之一&#xff08;增删改查&#xff09;&#xff0c;通常都会借助插入的方法增添信息&#xff0c;这一部分为大家着重讲解插入法。 1.头插法 简而言之&#xff0c;就是从链表的头部进行一个插入&#xff0c;定义一个结构体指针的新节点&#xff0c;…

【数据结构】:单链表之头插法和尾插法(动图+图解)

头插法和尾插法 一、头插法&#x1f4a4;思考一&#xff1a;头插法的核心是什么❓❗❗ 重点一&#xff1a;以带头结点方式实现头插法❗❗ 重点二&#xff1a;以不带头结点方式实现头插法 二、尾插法&#x1f4a4;思考二&#xff1a;尾插法的核心是什么❓❗❗ 重点三&#xff1a…

链表:头插法与尾插法(简易图解和代码)

头插法 定义&#xff1a;输入的数据次序生成的链表节点次序相反&#xff0c;例如&#xff1a;按1,2,3顺序进行头插之后&#xff0c;最终排序却变成了3,2,1。简而言之就是逆序插入。 定义图解&#xff1a; 代码图解&#xff1a; 代码&#xff1a;&#xff08;使用头插法建立单…

未声明的标识符

出现未声明的标识符错误&#xff0c;有可能是真的没有声明。但是也有可能是代码中有些注释&#xff0c;格式不对&#xff0c;导致声明的变量的作用域提前结束了。可以把注释都删掉试试

c2065 未声明的标识符 解决ok

场景1&#xff1a; cv::Mat pad_img; cv::Mat img; img 在一个if else后面声明&#xff0c;就报错了 解决方法&#xff0c;把cv::Mat 声明放到前面就行了&#xff0c;原因未知。 场景2&#xff1a; int a3; a为未声明的标识符&#xff0c;加了各种头文件&#xff0c;都不起…

已经包含头文件仍然出现,错误C2065“未声明的标识符”

由于当前在往一个比较大的项目中添加文件&#xff0c;文件又有相似性所以采取了复制的方式&#xff0c;最后出现了一个大疏漏。 在总的.cpp文件中调用新文件中的函数&#xff0c;在包含了新文件的.h头文件的情况下仍然说没有找到标识符&#xff0c;在网上找了很多方法&#xff…