数据结构之单链表(c++(c语言)通用版)

news2024/11/24 7:48:38

我们创建一个长度为n的链表时,可以采取头插法创建或者尾插法创建,本篇博客我们采取头插法来创建,(作者只学了头插,尾插等以后来补qwq,补上喽)。

头插原理

我们先来画图来看看头插的创建形式把,会了原理再写代码。

首先是我们的一号和二号节点,我们发现他们是相连的。现在我们使用头插法创建链表要怎么做呢,其实很简单,头插就是把我们新创建的节点放到最前面,我们每次都把创建的节点放到最前面,也就是1好节点的后面。大家注意了,这个一号节点不要存储任何数据或者(这能存储链表的长度信息,)它是我们的头节点。我们创建它只是为了好遍历以后的节点信息。

看图:

我们把一号节点的next地址连接到三号节点,三号的next地址连接到2号节点上,这就是头插。

上代码解释:

头插详细代码

void InitList(LinkedList a,int n){
	int e;
	for(e=0;e<n;e++){
		Lnode *b=(Lnode*)malloc(sizeof(Lnode));
		b->a=e;
		b->next=a->next;
		a->next=b;
	}
}
//a号节点是指向节点,我们之后创建的节点都是不断放在a号节点的后面,a号节点只是用来方便遍历。
//我们创建一个b节点,并为他的数据域赋予数值,接着,我们令b号节点链接a号节点链接的节点,并使得a号节点可以连接到b号节点。
//如果是一开始,只有指向a号节点,我们就相当于创建一个尾节点,指向空,令a号节点联系到尾节点

结构体代码:

typedef struct Lnode{
	int a;
	struct Lnode* next;
}Lnode,*LinkedList;//创建结构体,把结构体的别名起为Lnode
//把结构体Lnode的指针起名为LinkedList
//学过Java的同学是不是DNA动了呢qwq

创建指向节点的代码:

void test(){
	LinkedList a=(LinkedList)malloc(sizeof(Lnode));//动态开辟空间

	a->next=NULL;//令指向节点的next指向域为NULL
	int b;
	cin>>b;//输入链表的长度
	InitList(a,b);
	for(int c=0;c<b;c++){//打印验证成果
		a=a->next;
		cout<<a->a<<endl;
	}
	free(a);//释放a的空间
}

头插总代码详细代码:

#include<bits/stdc++.h>
using namespace std;
typedef struct Lnode{
	int a;
	struct Lnode* next;
}Lnode,*LinkedList;
void InitList(LinkedList a,int n){
	int e;
	for(e=0;e<n;e++){
		Lnode *b=(Lnode*)malloc(sizeof(Lnode));
		b->a=e;
		b->next=a->next;
		a->next=b;
	}
}
void test(){
	LinkedList a=(LinkedList)malloc(sizeof(Lnode));
	a->next=NULL;
	int b;
	cin>>b;
	InitList(a,b);
	for(int c=0;c<b;c++){
		a=a->next;
		cout<<a->a<<endl;
	}
	free(a);
}
int main(){
test();

	return 0;
}

运行结果:

大家可以看到这个6是我输入的,5到0为答案。为什么呢,我们采用头插,会把新创建的节点不断往前安防,而我们赋值又是从0开始,这就使得我们的最后一次赋值5用头插放到最前面了。

按照约定补上尾插:

尾插法原理:

尾插简单多了,顾名思义我们每次都插在最后面即可,别忘记最后一个节点要给他的next域赋值为NULL

尾插代码:

void creatweicha(LinkedList a,int length){
	Lnode* b=a;//创建指向节点来作为我们的指向
	int c=0;
	for(c=1;c<=2length;c++){///从1开始创建节点
		Lnode* p=(Lnode*)malloc(sizeof(Lnode));
		p->shuju=c;//节点存储的值为1到n
		b->next=p;//让指向节点链接到我们创建的节点上
		b=p;//同时移动指向节点让其指向我们创建的节点,以方便以后继续尾插
	}
	b->next=NULL;//别忘记最后一个节点的next域要赋值为NULL
}

在单链表中位置n插入一个元素代码

bool LinkedList_L(LinkedList a,int blocation,int c){
	int d=0;
	Lnode* p=(Lnode*)malloc(sizeof(Lnode));//动态开辟节点p来寻找查询节点的前驱节点
	p=a;
	while(true){
		d++;//d代表着我们这是第几号节点,节点编号从1号开始
		p=p->next;//不断使得p节点往后移动
		if(blocation<=0||p==NULL){//如果位置非法或者插入位置的前驱节点为NULL则代表着不存在前驱
			return false; //节点,返回false代表无法插入
		}
			if(d==blocation-1){
			break;//如果找到前驱节点那么结束循环
		}
	}
	Lnode* n=(Lnode*)malloc(sizeof(Lnode));
	n->shuju=c;//创建节点,并赋予其初始值
	n->next=p->next;//插入节点链接后面的节点
	p->next=n;//链接前驱节点
	return true;
	
}

附带插入函数的头插建立单链表附带验证的总代码:

#include<bits/stdc++.h>
using namespace std;
typedef struct Lnode{
	int shuju;
	struct Lnode* next;
}Lnode,*LinkedList;
void InitList(LinkedList a,int b){
	int c;
	for(c=1;c<=b;c++){
		Lnode* p=(Lnode*)malloc(sizeof(Lnode));
		p->shuju=c;
		p->next=a->next;
		a->next=p;
	}
}
bool LinkedList_L(LinkedList a,int blocation,int c){
	int d=0;
	Lnode* p=(Lnode*)malloc(sizeof(Lnode));
	p=a;
	while(true){
		d++;
		p=p->next;
		if(blocation<=0||p==NULL){
			return false; 
		}
			if(d==blocation-1){
			break;
		}
	}
	Lnode* n=(Lnode*)malloc(sizeof(Lnode));
	n->shuju=c;
	n->next=p->next;
	p->next=n;
	return true;
	
}
void testtoucha(){
	LinkedList a=(LinkedList)malloc(sizeof(Lnode));
	a->next=NULL;
	int b;
	cin>>b;
	InitList(a,b);
	Lnode* a1=a;
	for(int c=0;c<b;c++){
		a1=a1->next;
		cout<<a1->shuju<<endl;
	}
	cout<<"--------------------------------------"<<endl;
	LinkedList_L(a,3,100);
	Lnode* b1=a;
	while(true){
		b1=b1->next;
		if(b1==NULL){
			break;
		}
		else{
			cout<<b1->shuju<<endl;
		}
	}
	free(a);
}
int main(){
	testtoucha();
	return 0;
}

我们可以看到,我们头插创建十个节点,在第三个节点处插入数值为100的节点。

删除指定位置的节点

bool shanchu(LinkedList a,int b){
	Lnode* c=a;//创建节点,并把指向节点给与其
	int d=0;
	while(true){
		c=c->next;//不断往后移动节点
		d++;//记录这是第几个节点,下表从1开始
		if(b<=0||c==NULL){//如果删除位置不合法,或者要删除的位置的前驱为空,直接返回删除失败
			return false;
		}
		if(d==b-1){
			break;//找到合法的前驱节点,结束循环
		}
	}
	Lnode* m=c->next;//定义节点m来确定删除的节点
	if(m==NULL){
		return true;//如果m已经为NULL那么就不用管了。
	}
	else{//不为空,则删除节点m
		c->next=m->next;
		free(m);
		return true;
	}
}

带有删除节点函数的尾插创建的单链表验证:

#include<bits/stdc++.h>
using namespace std;
typedef struct Lnode{
	int shuju;
	struct Lnode* next;
}Lnode,*LinkedList;
bool shanchu(LinkedList a,int b){
	Lnode* c=a;
	int d=0;
	while(true){
		c=c->next;
		d++;
		if(b<=0||c==NULL){
			return false;
		}
		if(d==b-1){
			break;
		}
	}
	Lnode* m=c->next;
	if(m==NULL){
		return true;
	}
	else{
		c->next=m->next;
		free(m);
		return true;
	}
}
void creatweicha(LinkedList a,int length){
	Lnode* b=a;
	int c=0;
	for(c=1;c<=2length;c++){
		Lnode* p=(Lnode*)malloc(sizeof(Lnode));
		p->shuju=c;
		b->next=p;
		b=p;
	}
	b->next=NULL;
}
void test(){
	LinkedList a=(LinkedList)malloc(sizeof(Lnode));
	a->next=NULL;
	int c;
	cin>>c;
	creatweicha(a,c);
	Lnode* p=a;
	while(true){
		p=p->next;
		if(p!=NULL){
			cout<<p->shuju<<endl;
		}
		else{
			break;
		}
	}
	cout<<"AAAAAAA"<<endl;
	shanchu(a,3);
	Lnode* p1=a;
	while(true){
		p1=p1->next;
		if(p1!=NULL){
			cout<<p1->shuju<<endl;
		}
	  else{
	  	break;
	  }
	}
	free(a);
	
}
int main(){
	test();
	return 0;
}

可以看到我们创建了9个节点,成功删除了第三号节点。

一点小更正:

如果大家要单独写初始化函数的化,那么初始化函数就必须要加引用:

带初始化函数的尾插法:

#include<bits/stdc++.h>
using namespace std;
typedef struct Lnode{
	int shuju;
	struct Lnode* next;
}Lnode,*LinkedList;
bool shanchu(LinkedList a,int b){
	Lnode* c=a;
	int d=0;
	while(true){
		c=c->next;
		d++;
		if(b<=0||c==NULL){
			return false;
		}
		if(d==b-1){
			break;
		}
	}
	Lnode* m=c->next;
	if(m==NULL){
		return true;
	}
	else{
		c->next=m->next;
		free(m);
		return true;
	}
}
void creatweicha(LinkedList a,int length){
	Lnode* b=a;
	int c=0;
	for(c=1;c<=length;c++){
		Lnode* p=(Lnode*)malloc(sizeof(Lnode));
		p->shuju=c;
		b->next=p;
		b=p;
	}
	b->next=NULL;
}
void chushihua(LinkedList &a){//加引用,不然初始化失败
	a=(LinkedList)malloc(sizeof(Lnode));
	a->next=NULL;
	
}
void test(){

	
		LinkedList a;
		 chushihua(a);//=(LinkedList)malloc(sizeof(Lnode));
		//a->next=NULL;
	int c;
	cin>>c;
	creatweicha(a,c);
	Lnode* p=a;
	while(true){
		p=p->next;
		if(p!=NULL){
			cout<<p->shuju<<endl;
		}
		else{
			break;
		}
	}
	cout<<"AAAAAAA"<<endl;
	shanchu(a,3);
	Lnode* p1=a;
	while(true){
		p1=p1->next;
		if(p1!=NULL){
			cout<<p1->shuju<<endl;
		}
	  else{
	  	break;
	  }
	}
	free(a);
	
}
int main(){
	test();
	return 0;
} 

头插亦同理

#include<bits/stdc++.h>
using namespace std;
typedef struct Lnode{
	int a;
	struct Lnode* next;
}Lnode,*LinkedList;
void InitList(LinkedList a,int n){
	int e;
	for(e=0;e<n;e++){
		Lnode *b=(Lnode*)malloc(sizeof(Lnode));
		b->a=e;
		b->next=a->next;
		a->next=b;
	}
}
void chushihua(LinkedList &a){
	a=(LinkedList)malloc(sizeof(Lnode));
	a->next=NULL;
}
void test(){
	LinkedList a;
	chushihua(a);//=(LinkedList)malloc(sizeof(Lnode));
	//a->next=NULL;
	int b;
	cin>>b;
	InitList(a,b);
	for(int c=0;c<b;c++){
		a=a->next;
		cout<<a->a<<endl;
	}
	free(a);
}
int main(){
test();

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《python趣味工具》——酷炫二维码(2):批量定制合适的二维码

今天&#xff0c;我们将学习如何从Excel中提取相应的内容然后批量生成相应的二维码。 文章目录 一、Excel的基本操作&#xff1a;1. Excel的基本结构&#xff1a;2. 安装xlrd模块&#xff1a;3. 读取指定工作表&#xff1a;4. 读取指定内容&#xff1a;Tip:切片读取&#xff1a…

线性代数的学习和整理19,特征值,特征向量,以及引入的正交化矩阵概念(草稿)

目录 1 什么是特征值和特征向量&#xff1f; 1.1 特征值和特征向量这2个概念先放后 1.2 直观定义 1.3 严格定义 2 如何求特征值和特征向量 2.1 方法1&#xff1a;结合图形看&#xff0c;直观方法求 2.1.1 单位矩阵的特征值和特征向量 2.1.2 旋转矩阵 2.2 根据严格定义…

buuctf crypto 【RSA2】解题记录

1.打开文件 2.写脚本 3.16进制转字符串

Ardupilot — AP_OpticalFlow代码梳理

文章目录 前言 1 Copter.cpp 1.1 void Copter::setup() 2 system.cpp 2.1 void Copter::init_ardupilot() 3 sensors.cpp 3.1 void Copter::init_optflow() 3.2 对象optflow说明 4 OpticalFlow.cpp 4.1 void OpticalFlow::init(uint32_t log_bit) 5 AP_OpticalFlow_…

十三、函数式编程(1)

本章概要 新旧对比Lambda 表达式 递归 函数式编程语言操纵代码片段就像操作数据一样容易。 虽然 Java 不是函数式语言&#xff0c;但 Java 8 Lambda 表达式和方法引用 (Method References) 允许你以函数式编程。 在计算机时代早期&#xff0c;内存是稀缺和昂贵的。几乎每个人…

手写Spring:第20章-事务处理

文章目录 一、目标&#xff1a;事务处理二、设计&#xff1a;事务处理2.1 事务单元测试2.2 事务设计 三、实现&#xff1a;事务处理3.1 工程结构3.2 事务管理的核心类图3.3 定义事务注解3.3.1 定义事务注解3.3.2 定义事务接口3.3.3 默认事务定义实现类3.3.4 委托事务定义实现类…

Java 多线程系列Ⅵ(并发编程的六大组件)

JUC 组件 前言一、Callable二、ReentrantLock三、Atomic 原子类四、线程池五、Semaphore六、CountDownLatch 前言 JUC&#xff08;Java.util.concurrent&#xff09;是 Java 标准库中的一个包&#xff0c;它提供了一组并发编程工具&#xff0c;本篇文章就介绍几组常见的 JUC 组…

win10自带wifi共享功能

1、按下【wini】组合键打开windows设置&#xff0c;点击【网络和internet】&#xff1b; 2、按照下图&#xff0c;打开个移动热点&#xff0c;设置名称、密码。

Blender--》页面布局及基本操作讲解

接下来我会在three.js专栏中分享关于3D建模知识的文章&#xff0c;如果学习three朋友并且想了解和学习3D建模&#xff0c;欢迎关注本专栏&#xff0c;关于这款3D建模软件blender的安装&#xff0c;我在前面的文章已经讲解过了&#xff0c;如果不了解的朋友可以去考考古&#xf…

DeepinV20安装MSJDK17

装什么版本的JDK https://learn.microsoft.com/zh-cn/java/openjdk/download#openjdk-17 通常来讲&#xff0c;选择最适应自己应用程序的版本&#xff0c;例如最新开发的程序基本需要运行在jdk17了&#xff0c;又或者前几年的java程序基本都是jdk11,再旧一点的jdk8。尽可能选…

【C++深入浅出】类和对象中篇(六种默认成员函数、运算符重载)

目录 一. 前言 二. 默认成员函数 三. 构造函数 3.1 概念 3.2 特性 四. 析构函数 4.1 概念 4.2 特性 五. 拷贝构造函数 5.1 概念 5.2 特性 六. 运算符重载 6.1 引入 6.2 概念 6.3 注意事项 6.4 重载示例 6.5 赋值运算符重载 6.6 前置和后置运算符重载 七. c…

【Rust日报】2023-09-07 Servo 项目将加入欧洲 Linux 基金会

Servo 项目将加入欧洲 Linux 基金会 Servo 项目由 Mozilla Research 于 2012 年创建&#xff0c;是除编译器本身之外的首个主要 Rust 代码库&#xff0c;自此成为实验性网络引擎设计的标志。Servo 的主要组件已被集成到 Firefox 网络浏览器中&#xff0c;其若干解析器和其他底层…

渗透测试基础之永恒之蓝漏洞复现

渗透测试MS17-010(永恒之蓝)的漏洞复现 目录 渗透测试MS17-010(永恒之蓝)的漏洞复现 目录 前言 思维导图 1,渗透测试 1,1,什么是渗透测试? 1.2,渗透测试的分类: 1.3,渗透测试的流程 1.3.1,前期交互 1.3.2,情报收集 1.3.3,威胁建模 1.3.4,漏洞分析 1.3.5,漏洞验…

软件设计模式(五):代理模式

前言 代理模式是软件设计模式的重中之重&#xff0c;代理模式在实际应用比较多&#xff0c;比如Spring框架中的AOP。在这篇文章中荔枝将会梳理有关静态代理、动态代理的区别以及两种实现动态代理模式的方式。希望能对有需要的小伙伴有帮助~~~ 文章目录 前言 一、静态代理 二…

自定义Dynamics 365实施和发布业务解决方案 - 1. 准备工作

在当前的商业世界中,竞争每时每刻都在加剧每个企业都必须找到在竞争中保持领先的直观方法。其中之一企业面临的主要挑战是在以便为客户提供更好的服务。在这样一个竞争激烈、要求苛刻的时代环境中,对客户关系管理软件的需求是正在增加。 Dynamics 365的CE功能强大且适应性强…

使用JS实现一个简单的观察者模式(Observer)

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 手撸Observer⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领…

MySQL数据库——存储引擎(1)-MySQL体系结构、存储引擎简介

目录 MySQL体系结构 连接层 服务层 引擎层 存储层 存储引擎简介 概念 语句 演示 下面开始学习进阶篇的第一个内容——存储引擎 分为四点学习&#xff1a; MySQL体系结构存储引擎简介存储引擎特点存储引擎选择 MySQL体系结构 连接层 最上层是一些客户端和链接服务&am…

小米和金山集团董事长雷军访问武汉:加大投资力度,深化务实合作

小米集团创始人雷军一行在9月6日到访了武汉&#xff0c;受到了当地政府的热情欢迎。武汉方面表示&#xff0c;小米、金山集团作为全球知名的企业集团&#xff0c;与武汉有着良好合作基础。未来&#xff0c;武汉希望小米、金山集团持续深耕武汉&#xff0c;加大投资力度&#xf…

主页整理:8月1日---9月10日

目录 8月1日17点 8月1日20点 8月3日13点 8月3日18点 8月15日19点 8月28日9点 8月28日18点 8月29日8点 8月29日9点 9月2日21点 9月5日17点 9月9日18点 9月10日7点 粉丝变化数 8月1日17点 8月1日20点 8月3日13点 8月3日18点 8月15日19点 8月28日9点 8月28日18点…

Element-ui container常见布局

1、header\main布局 <template> <div> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> </div> </template> <style> .el-header { …