单链表的建立(头插法、尾插法)(数据结构与算法)

在这里插入图片描述

如果要把很多个数据元素存到一个单链表中,如何操作?
1.初始化一个单链表
2. 每次取一个数据元素,插入到表尾/表头

1. 尾插法建立单链表

尾插法建立的单链表元素顺序与输入数据集合的顺序相同,即按照输入数据的顺序排列。

使用尾插法建立单链表的一个常见应用是在计算机科学中进行数据输入。通过将用户输入的数据逐个添加到链表的尾部,可以方便地保存输入的数据,并在后续处理中使用。

  1. 初始化单链表
  2. 设置变量length纪录链表长度
  3. while循环{
  4. 每取一个元素e;
  5. ListInsert(L, length+1, e) 插入到尾部;
  6. length++;}
    在这里插入图片描述

尾插法(尾部插入法)是一种建立单链表的常用方法,与头插法相反,它会将新节点插入到链表的尾部位置。以下是使用尾插法建立单链表的步骤:

  1. 首先定义一个头节点,并将其初始化为空指针。
  2. 遍历需要转化为链表的数据集合。
  3. 对于数据集合中的每一个元素,创建一个新的节点,并设置其数据域为该元素的值。
  4. 若链表为空,将新节点直接设置为头节点。
  5. 若链表非空,则遍历到链表的最后一个节点,并将其指针域指向新节点。
  6. 更新链表的最后一个节点为新节点。
typedef struct LNode      //定义单链表结点类型
{
	ElemType data;		  //每个结点存放一个数据元素
	struct LNode *next;   //指针指向下一个节点
}
//初始化一个单链表(带头结点)
bool InitList(LinkList &L)  
{
	L = (LNode *)  malloc(sizeof(LNode)); //分配一个头结点
	if (L == NULL) 		 //内存不足, 分配失败
		return false;
	L->next = NULL; 		//头结点之后暂时还没有节点
	return true;	
}
void test()
{
	LinkList L;   //声明一个指向单链表的指针
	//初始化一个空表
	InitList(L);
	//......后续代码......
}

//在第i个位置处插入元素e(带头结点)
bool ListInsert(LinkList &L, int i, ElemType e)
{
	if(i<1)
		return false;
	LNode *p;		//指针p指向当前扫描到的节点
	int j = 0; 		//指针p指向的是第几个结点
	p = L;		//L指向头结点 头结点是第0个结点,不存数据
	while( p != NULL && j < i-1) //循环找到第i-1个结点
	{
		p = p->next;
		j++;
	}
	if( p==NULL)	//i值不合法
		return false;
	LNode *s = (LNode *) malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;		//将结点s连到p之后
	return true;		//插入成功
}

当插入1个元素时,while需要循环一次,插入2个元素,while循环1此…插入n个元素,while循环n-1次。 每次都从开头开始之后遍历,循环次数为1+2+3+…+(n-1)。时间复杂度为0(n^2)

这种操作,时间复杂度太大,并不是最佳方案。

其实根本没必要每次都从头开始往后寻找, 我们可以设置一个指针r,指向表尾,当要在尾部插入一个新的数据元素时,就只需要对r结点做一个后插操作就行了。

//后插操作: 在p结点之后插入元素e
bool InsertNode(LNode *p, ElemType e)
{
	if(p == NULL)
		return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if(s==NULL)		//内存分配失败
		return false;
	s->data = e;		//用结点s保存数据元素
	s->next = p->next;   
	p->next = s; 		//将结点s连到p之后    后插操作
	return true;				
}

在这里插入图片描述

插入数据元素40

在这里插入图片描述

尾部插入一个元素,表尾指针后移一位,仍然指向最后一个元素,方便下一次插入

在这里插入图片描述

示例:尾插法建立单链表

设此次输入的整数是10,while循环检测,循环中前两句,会申请一个新的结点,然后让s这个指针指向新结点,并且把输入的x = 10放入新结点中,接下来把 r结点的next指针指向s结点。最后,再让r指针指向s结点,接下来就可以输入下一个元素x,继续插入。

时间复杂度:O(n)

LinkList List_TailInsert(LinkList &L)
{
	int x;		//设ElemType为整型
	L = (LinkList)malloc(sizeof(LNode));	//建立头结点
	LNode *s, *r = L;	//r为表尾指针
	scanf("%d", &x);	//输入结点的值
	while(x != 9999)    //该数是随便取的 ,输入9999表示结束
	{
		s = (LNode *) malloc(sizeof(LNode));  //简历一个结点s
		s->data = x; 	//将x存放到s数据域中
		r->next = s; //将表尾指针指向s结点
		r = s;	//r指向新的表尾结点
		scanf("%d",&x);
	}
	r->next = NULL; 	//尾结点指针置空
	return L;
}

LNode *s, *r = L; //r为表尾指针

在这里插入图片描述

申请一个新的结点,然后让s这个指针指向新结点,并且把输入的x = 10放入新结点中

在这里插入图片描述

接下来把 r 结点的next指针指向s结点

在这里插入图片描述

最后,再让r指针指向s结点, 接下来就可以输入下一个元素x,继续插入

在这里插入图片描述

假设继续输入 x = 16。那么会再申请一个新的结点s,让s指针指向新节点, 并把16放入新结点, 接下来把r结点的指针指向s结点, 最后…

在这里插入图片描述

将 r 指针指向s结点,再输入下一个元素27 。 以此类推完成插入操作。

在这里插入图片描述

如果x输入的是9999, 那么就可以跳过while循环,执行r->next = NULL; 让r结点的next指向NULL。
在这里插入图片描述

2. 头插法建立单链表

头插法建立单链表的特点是:新节点插入到链表的头部位置,因此建立完成的链表元素顺序是和输入数据集合的顺序相反的,即倒序排列。

对头结点的后插操作,如下图所示:

  1. 首先定义一个头节点,并将其初始化为空指针。
  2. 遍历需要转化为链表的数据集合。
  3. 对于数据集合中的每一个元素,创建一个新的节点,并设置其数据域为该元素的值。
  4. 将新节点的指针域指向当前头节点,即将新节点插入到链表的头部。
  5. 更新头节点为新节点。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//后插操作:在p结点之后插入元素e
bool InsertNextNode(LNode *p, ElemType e)
{
	if(p == NULL)
		return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if(s == NULL)	//内存分配失败
		return false;	
	s->data = e;		//用结点s保存数据元素e
	s->next = p->next;
	p->next = s;		//将结点s连接到p之后
	return true;
}

在这里插入图片描述

  • 如上图所示,此处,尾插法中是没有 L->next = NULL 这一句的,但在头插法中,这句非常必要。由于是动态分配,如果头结点指向没有被初始化为NULL,那头结点L->next 很有可能指向了内存中某一神秘区域,从而形成脏数据,影响后面的插入操作。

养成好习惯,只要是初始化单链表,都先把头指针指向NULL

  • 按照头插法形成的规则,最终形成的单链表刚好是输入元素的逆序,这种性质非常重要!!!
    很多题目中都用得到单链表的逆置。
    在这里插入图片描述

3. 知识点回顾

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/115045.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

心理咨询预约小程序

随着微信小程序的日益普及&#xff0c;越来越多的人开始关注如何利用小程序来提供便捷的服务。对于心理咨询行业来说&#xff0c;搭建一个心理咨询预约小程序可以大大提高服务的效率和用户体验。本文以乔拓云平台为例&#xff0c;详细介绍如何轻松搭建一个心理咨询预约小程序。…

甘特图组件DHTMLX Gantt用例 - 如何拆分任务和里程碑项目路线图

创建一致且引人注意的视觉样式是任何项目管理应用程序的重要要求&#xff0c;这就是为什么我们会在这个系列中继续探索DHTMLX Gantt图库的自定义。在本文中我们将考虑一个新的甘特图定制场景&#xff0c;DHTMLX Gantt组件如何创建一个项目路线图。 DHTMLX Gantt正式版下载 用…

R语言的DICE模型实践技术

随着温室气体排放量的增大和温室效应的增强&#xff0c;全球气候变化问题受到日益的关注。我国政府庄严承诺在2030和2060年分别达到“碳达峰”和“碳中和”&#xff0c;因此气候变化和碳排放已经成为科研人员重点关心的问题之一。气候变化问题不仅仅是科学的问题&#xff0c;同…

百度百科怎么创建?百科创建需要注意哪些(一文看懂品牌/企业/人物百科创建)

随着互联网的不断发展&#xff0c;许多企业或品牌都选择创建百度百科作为一种很好的展示方式。百度百科可以被视为一张网络名片&#xff0c;拥有它能够提高人物、企业、品牌的知名度和影响力。那么人物百科、企业百科、品牌百科到底怎么创建呢&#xff1f; 大家创建百科前建议先…

【Python】

列表 列表中元素的类型可以不同&#xff0c;列表内部存储方式是元素值存储在不连续的空间&#xff0c;但是把他们的指针存在一块连续的空间 列表的创建 1.list1[] 创建一个空列表 2.用list函数 3.split函数截取 列表的更新 1.通过索引[]改变 2.切片修改 3.列表方法更新 列表…

高级 Python:函数

伊利亚拉扎列维奇 一、说明 读完标题后&#xff0c;你可能会问自己一些类似的事情&#xff0c;“Python 中的函数是一个高级概念&#xff1f;如何&#xff1f;所有课程都引入了功能作为语言的基本块。你既是对的&#xff0c;也是错的。 大多数关于 Python 的课程都将函数作为基…

银行账单转换beancount

用了beancount来记账后&#xff0c;发现每月的账单手动记是一件极其麻烦的事情。 然后再github搜索一通后&#xff0c;有double-entry-generator&#xff08;https://github.com/deb-sig/double-entry-generator&#xff09;能转换支付宝/微信的账单&#xff0c;但是没有自己用…

Prometheus+Node_exporter+Grafana实现监控主机

PrometheusNode_exporterGrafana实现监控主机 如果没有安装相关的配置&#xff0c;首先要进行安装配置&#xff0c;环境是基于Linux&#xff0c;虚拟机的相关环境配置在文末给出&#xff0c;现在先讲解PrometheusNode_exporterGrafana的安装和使用。 一.Prometheus安装 虽然…

vue-浏览器安装Vue开发者工具

极简插件&#xff1a;下载->开发者模式->拖曳安装->插件详情允许访问文件 网址&#xff1a;https://chrome.zzzmh.cn/index 搜索Vue Devtools 下载下来的安装包先解压 然后点击chrome浏览器的右上角三个点的按钮在里面找到扩展程序这个选项&#xff0c;然后点进去管理…

我在Vscode学OpenCV 基本的加法运算

根据上一篇我们可知__图像的属性 链接&#xff1a;《我在Vscode学OpenCV 处理图像》 属性— API 形状 img.shape 图像大小 img.size 数据类型 img.dtype  shape&#xff1a;如果是彩色图像&#xff0c;则返回包含行数、列数、通道数的数组&#xff1b;如果是二值图像或者灰度…

Java高级互联网架构师之路:垃圾回收器的介绍

本文重点 从本文开始我们将开启垃圾回收器的介绍了,我们知道垃圾回收算法是逻辑改变,而垃圾回收器是具体的实现。我们前面介绍的垃圾回收器有7个,本文将在添加三个,但是这三个目前来看不是很常用,我们只了解一下,我们主要还是讲解这7个垃圾回收器。 十个垃圾回收器 目…

【漏洞库】XXL-JOB 默认accessToken权限绕过导致RCE

文章目录 漏洞描述漏洞编号漏洞评级影响版本漏洞复现- EXP 编写 漏洞挖掘修复建议 漏洞描述 XXL-JOB 是一款开源的分布式任务调度平台&#xff0c;用于实现大规模任务的调度和执行。 XXL-JOB 默认配置下&#xff0c;用于调度通讯的 accessToken 不是随机生成的&#xff0c;而…

如何记录每天的工作日程?电脑手机通用的日程管理软件

在工作时间有限&#xff0c;但工作任务愈加繁多的现在职场中&#xff0c;要求每一个职场人士做好高效日程管理。通过高效管理日程&#xff0c;我们可以更好地组织和安排任务&#xff0c;合理分配时间和优先级&#xff0c;这有助于我们更专注地进行工作&#xff0c;减少时间的浪…

手写操作系统篇:实现裸机应用程序

文章目录 前言操作系统执行环境创建裸机平台项目Rust的Core库移除标准库依赖Qemu 启动流程内存布局编译流程内核的初始指令调整内核的内存布局手动加载内核可执行文件使用RustSBI提供的服务添加bootloader模块添加Makefile运行停止总体架构 前言 我们既然是手写操作系统&#…

行业追踪,2023-11-03

自动复盘 2023-11-03 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

学习小结,学而时习之,坚持学习之,温顾学习之

学习python一个多月了&#xff0c;之前也有接触过&#xff0c;还花了不少钱报班&#xff0c;看了看入门的头两节课&#xff0c;就止步了。每一种编程语言的入门感觉都差不多&#xff0c;学到现在&#xff0c;我对python的基本数据类型还是没掌握好啊&#xff0c;每次列表字典怎…

js 根据word文档模板导出内容

一、创建word导出模板 1、本地创建一个test.docx 2、将最终需要的文档内容及样式编辑完成(图1) 3、将所需动态值的位置,替换为变量参数(图2) 注: 动态值书写 图1 图2 模板值的书写要求 二、项目中使用 1、安装依赖 npm install docxtemplater-image-module-free --save n…

4+m6A+机器学习+分型,要素过多,没有思路的同学可借鉴

今天给同学们分享一篇生信文章“Diagnostic, clustering, and immune cell infiltration analysis of m6A regulators in patients with sepsis”&#xff0c;这篇文章发表在Sci Rep.期刊上&#xff0c;影响因子为4.6。 结果解读&#xff1a; 脓毒症中m6A调节因子的转录改变 …

[PyTorch][chapter 61][强化学习-免模型学习1]

前言&#xff1a; 在现实的学习任务中&#xff0c;环境 其中的转移概率P,奖赏函数R 是未知的&#xff0c;或者状态X也是未知的 称为免模型学习&#xff08;model-free learning&#xff09; 目录&#xff1a; 1: 蒙特卡洛强化学习 2&#xff1a;同策略-蒙特卡洛强化学习 3&am…

非关系型数据库Redis的安装【Linux】及常用命令

前言 Redis&#xff08;Remote Dictionary Server&#xff09;是一种开源的内存数据库管理系统&#xff0c;它以键值存储方式来存储数据&#xff0c;并且支持多种数据结构&#xff0c;如字符串、哈希、列表、集合、有序集合等。Redis最初由Salvatore Sanfilippo开发&#xff0c…
最新文章