【单链表】

news2024/11/15 11:57:30

单链表

  • 1. 函数的声明部分
  • 2. 函数的实现部分
    • (1)打印链表
    • (2)头插
    • (3)尾插
    • (3)头删
    • (4)尾删
    • (5)单链表的查找
    • (6)删除pos位置之后的值
    • (7)在pos位置之后插入x
  • 3. 函数的测试部分

单链表概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

1. 函数的声明部分

		#pragma once
		#include <stdio.h>
		#include <stdlib.h>
		#include <assert.h>
		
		typedef int SLTDateType;
		
		typedef struct SingleListNode
		{
		
			SLTDateType data;
			struct SingleListNode* next;
		
		}SLTNode;
		
		
		//打印
		void SLTPrint(SLTNode* phead);
		
		//头插
		void SLTPushFront(SLTNode** pphead, SLTDateType x);
		
		//尾插
		void SLTPushBack(SLTNode** pphead, SLTDateType x);
		
		//头删
		void SLTPopFront(SLTNode** pphead);
		
		//尾删
		void SLTPopBack(SLTNode** pphead);
		
		//在pos位置之后插入x
		void SLTInsertAfter(SLTNode* pos, SLTDateType x);
		
		//删除pos位置之后的值
		void SLTEraseAfter(SLTNode* pos);
		
		//单链表查找
		SLTNode* SLTFind(SLTNode** pphead, SLTDateType x);

2. 函数的实现部分

由于头插,尾插等需要开辟一个节点,所以把开辟节点单独作为一个函数,需要开辟节点的时候直接调用;

		SLTNode* BuyListNode(SLTDateType x)
		{
			//开辟一个节点
			SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
			assert(newnode);
		
			//对newnode初始化
			newnode->data = x;
			newnode->next = NULL;
		
			return newnode;
		}

(1)打印链表

		//打印
		void SLTPrint(SLTNode* phead)
		{
			SLTNode* cur = phead;
			while (cur)
			{
				printf("%d->", cur->data);
				cur = cur->next;
			}
			printf("NULL\n");
		}

(2)头插

头插需要传二级指针,因为在调用函数SLTPushFront的时候,实参plist本来是结构体指针,现在头插需要改变链表的头,即需要传地址去改变plist的头;

如进行以下操作,值传递操作:

在这里插入图片描述
在这里插入图片描述
假设链表是如下形式:

在这里插入图片描述

当头插函数使用一级指针接收实参时,实参和形参同为一级指针,它们是同等类型的,它们在两个不同的栈空间,假如进行以下操作:

在这里插入图片描述
实际上phead并不会改变plist的值:

在这里插入图片描述

因为它们两个在不同的栈空间,phead只是plist的临时拷贝,只要出了SLTPushFront这个函数,栈帧被销毁,phead也被销毁了,但是phead的改变也没有改变plist的值,所以相当于什么也没有发生;

所以需要传二级指针,存放plist的指针,到函数内部需要解引用找到plist,再去改变plist的值,这样才能达到我们想要的效果;

		//头插
		void SLTPushFront(SLTNode** pphead, SLTDateType x)
		{
			SLTNode* newnode = BuyListNode(x);
			
			//将newnode的next更新为原来的头节点
			newnode->next = *pphead;
		
			//将newnode更新为新的头节点
			*pphead = newnode;
		
		}

(3)尾插

尾插的时候,当链表为空时,需要改变的是plist这个结构体指针,所以这个时候也是要传二级指针;当链表为非空链表时,需要改变的是结构体,所以不需要用到二级指针;但为了防止链表为空,这里干脆直接传二级指针;

		//尾插
		void SLTPushBack(SLTNode** pphead, SLTDateType x)
		{
		
			SLTNode* newnode = BuyListNode(x);
		
			//空链表
		 	if (*pphead == NULL)
			{
				*pphead = newnode;
			}
		
			//非空链表
			else
			{
				SLTNode* tail = *pphead;
		
				while (tail->next)
				{
					tail = tail->next;
				}
		
				tail->next = newnode;
			}
		}

(3)头删

		//头删
		void SLTPopFront(SLTNode** pphead)
		{
			//没有节点
			assert(*pphead);
		
			//一个节点
			if ((*pphead)->next == NULL)
			{
				free(*pphead);
				*pphead = NULL;
			}
		
			//多个节点
			else
			{
				SLTNode* cur = *pphead;
				*pphead = cur->next;
		
				free(cur);
				cur = NULL;
			}
		}

(4)尾删

		//尾删
		void SLTPopBack(SLTNode** pphead)
		{
			//空链表
			assert(*pphead);
		
			//一个节点
			if ((*pphead)->next == NULL)
			{
				free(*pphead);
				*pphead = NULL;
			}
		
			//多个节点
			else
			{
				SLTNode* tail = *pphead;
		
				while (tail->next->next)
				{
					tail = tail->next;
				}
		
				free(tail->next);
				tail->next = NULL;
			}
		}

(5)单链表的查找

		SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
		{
			SLTNode* cur = phead;
		
			while (cur)
			{
				if (cur->data == x)
				{
					return cur;
				}
				cur = cur->next;	
			}
			return NULL;
		}

(6)删除pos位置之后的值

		void SLTEraseAfter(SLTNode* pos)
		{
			assert(pos && pos->next);
		
			SLTNode* cur = pos;
		
			cur->next = cur->next->next;
		}

(7)在pos位置之后插入x

		void SLTInsertAfter(SLTNode* pos, SLTDateType x)
		{
			SLTNode* cur = BuyListNode(x);
			assert(cur);
		
			cur->next = pos->next;
			pos->next = cur;
		}

3. 函数的测试部分

		#define _CRT_SECURE_NO_WARNINGS 1
		#include "Single List.h"
		
		int main()
		{
			SLTNode* plist = NULL;
		
			SLTPushFront(&plist, 2);
		
		
			SLTPushFront(&plist, 1);
		
			SLTPushBack(&plist, 3);
			SLTPushBack(&plist, 4);
			SLTPushBack(&plist, 5);
		
			//SLTPopFront(&plist);
			
		
			//SLTPopBack(&plist);
		
		
			//SLTInsertAfter(plist->next->next, 10);
		
		
			SLTEraseAfter(plist);
			
		
			SLTPrint(plist);
		
			
		
			SLTNode* ret = SLTFind(plist, 5);
			if (ret != NULL)
			{
				printf("%d->", ret->data);
			}
			else
			{
				printf("NULL\n");
			}
		
		
			SListDestroy(&plist);
		
			return 0;
		}

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

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

相关文章

leetcode 879. Profitable Schemes(有利润的计划)

有几个工程&#xff0c;每个工程需要group[ i ]个人去做&#xff0c;做完了可以得到profit[ i ]的利润。 现有2个限制条件&#xff1a; 人数上限是n, 且参加了一个工程的人不能再参加其他工程。 利润下限minProfit, 至少要获得minProfit的利润。 问有多少种工程的选法&#xff…

Zuul源码解析(一)

说在前面 我们公司有一个线上服务报错通知群&#xff0c;经常报网关服务的一个 EOFException 异常。这个异常报出来好久了&#xff0c;如下图所示&#xff0c;艾特相关的人也不去处理&#xff0c;大概是不重要异常吧&#xff0c;反正看样子是不影响线上核心业务流程。 然后我上…

FreeRTOS学习笔记(一)——初识FreeRTOS

FreeRTOS官网&#xff1a;FreeRTOS - 适用于具有物联网扩展功能的嵌入式系统的市场领先 RTOS&#xff08;实时操作系统&#xff09; FreeRTOS源码下载&#xff1a;FreeRTOS Real Time Kernel (RTOS) - Browse /FreeRTOS at SourceForge.net 目录 0x01 FreeRTOS编程风格 一…

用CentOS服务器自己搭建部署个Discuz论坛网站,网站搭建教程

Linux系统CentOS服务器使用堡塔搭建论坛网站全套教程。服务器大本营&#xff0c;技术文章内容集合站发车啦&#xff01; 操作系统&#xff1a;Centos 7.6 网站程序&#xff1a;Discuz-X3.4 前言 首先&#xff0c;搭建一个网站需要准备&#xff1a;服务器、域名、网站程序。 …

PWM控制直流电机

一&#xff0c;TB6612电机驱动模块 直流电机属于大功率器件&#xff0c;GPIO无法直接驱动&#xff0c;需要电机驱动模块配合&#xff0c;才能驱动直流电机. TB6612可以驱动2个直流电机。由IN1&#xff0c;IN2控制电机旋转方向&#xff0c;由PWM控制电机旋转速度。 二&#xf…

基于Oracle VM VirtualBox的ubuntu的安装

基于Oracle VM VirtualBox的ubuntu的安装 感谢詹老师的帮助使我得以完成本次安装&#xff0c;以下为本次安装的一个小小的记录。 目录 基于Oracle VM VirtualBox的ubuntu的安装Oracle VM VirtualBox的下载与安装ubuntu的下载Oracle VM VirtualBox下安装ubuntu安装 ROS Melodi…

GitHub 开源神器 Bark模型,让文本转语音更简单

今天跟大家分享一个文本转语音的开源模型&#xff1a;Bark Bark 是由Suno创建的基于转换器的文本到音频模型。Bark 可以生成高度逼真的多语言语音以及其他音频 - 包括音乐、背景噪音和简单的音效。该模型还可以产生非语言交流&#xff0c;如大笑、叹息和哭泣。 该项目刚开源不…

二叉树OJ题(C++实现)

文章目录 1.二叉树创建字符串2. 二叉树的最近公共祖先3.二叉搜索树与双向链表4.从前序与中序遍历序列构造二叉树 1.二叉树创建字符串 二叉树的层序遍历 OJ连接 主要思路是借助一个队列&#xff0c;将每一层的数据以size统计&#xff0c;当size为0时说明该层数据已经输入完&…

Unity Physics2D 2d物理引擎游戏 笔记

2d 材质 里面可以设置 摩擦力 和 弹力 Simulated&#xff1a;是否在当前的物理环境中模拟&#xff0c;取消勾选该框类似于Disable Rigidbody&#xff0c;但使用这个参数更加高效&#xff0c;因为Disable会销毁内部产生的GameObject&#xff0c;而取消勾选Simulated只是禁用。…

详解C语言string.h中常用的14个库函数(四)

本篇博客会讲解最后4个函数&#xff0c;分别是memset, memcpy, memmove, memcmp。这4个函数开头都是mem&#xff0c;即memory&#xff08;内存&#xff09;的缩写。 memset void * memset ( void * ptr, int value, size_t num );memset可以用来设置内存中的值。该函数可以把从…

深度学习实战——循环神经网络(RNN、LSTM、GRU)

忆如完整项目/代码详见github&#xff1a;https://github.com/yiru1225&#xff08;转载标明出处 勿白嫖 star for projects thanks&#xff09; 目录 系列文章目录 一、实验综述 1.实验工具及内容 2.实验数据 3.实验目标 4.实验步骤 二、循环神经网络综述 1.循环神经…

【数据结构】第五章 树与二叉树

文章目录 知识体系5.1 树的基本概念5.1.1 树的定义5.1.2 基本术语5.1.3 树的性质 5.2 二叉树的概念5.2.1 二叉树的定义和主要特性5.2.2 二叉树的存储结构 5.3 二叉树的遍历和线索二叉树5.3.1 二叉树的遍历5.3.2 线索二叉树 5.4 树、森林5.4.1 树的存储结构5.4.2 树、森林与二叉…

uniapp踩坑之项目:各端条件编译

在 HBuilderX 中&#xff0c;ctrlalt/ 即可生成正确注释&#xff08;js&#xff1a;// 注释、css&#xff1a;/* 注释 */、vue/nvue模板&#xff1a; &#xff09;。 #ifdef&#xff1a;if defined 仅在某平台存在#ifndef&#xff1a;if not defined 除了某平台均存在%PLATFORM…

ARM busybox 的移植实战2

一、busybox 源码分析1 1、源码目录梳理 2、整个程序入口的确认 (1) 分析一个程序&#xff0c;不管多庞大还是小&#xff0c;最好的路线都是 按照程序运行时的逻辑顺序来。所以找到一个程序的入口至关重要。 (2) 学 C 语言的时候都知道&#xff0c;程序的主函数 main 函数就是…

机器学习算法 随机森林

文章目录 一、概述1.1 集成学习1.2 决策树1.3 随机森林 二、Sklearn中的随机森林2.1 分类树API2.2 参数 2.2 回归树API2.2.1 重要参数 2.3 随机森林调参 三、总结 一、概述 1.1 集成学习 多个模型集成成为的模型叫做集成评估器&#xff08;ensemble estimator&#xff09;&am…

车载软件架构——闲聊几句AUTOSAR BSW(二)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 我特别喜欢一个老话,来都来了。我觉得这就是松弛感,既然来了,就开心起来吧!松弛感来自于专注,焦虑不是靠克服的,是靠忘记的,当你很专注做一件事的时候…

HNCTF-re部分复现

目录 [HNCTF 2022 WEEK3]Help_Me! [HNCTF 2022 WEEK3]Whats 1n DLL? [HNCTF 2022 WEEK4]ez_maze 这几天在做HNCTF的week3&#xff0c;week4部分&#xff0c;学到了一些不知道的没接触过的东西&#xff0c;所以记录一下 [HNCTF 2022 WEEK3]Help_Me! 题目下载&#xff1a;下…

onnx笔记2:onnx操作实例

1. 介绍 本文以yolov5s模型,演示对yolov5s.onnx模型文件的读取,修改等操作 2. onnx操作 2.1 获取数据 (1) 案例1 :读取weights数据 比如获取yolov5s.onnx第一个Conv的weights数据。 点击左侧第一个Conv, 右侧INPUTS下面的W点开+号,可以看到该Conv的weight的name为m…

MySQL --- 主从复制、读写分离

一、MySQL主从复制 MySQL数据库默认是支持主从复制的&#xff0c;不需要借助于其他的技术&#xff0c;我们只需要在数据库中简单的配置即可。接下来&#xff0c;我们就从以下的几个方面&#xff0c;来介绍一下主从复制 1.1、介绍 MySQL主从复制是一个异步的复制过程&#xff0c…

linux 安装 oracle 11g

linux 安装 oracle 11g 1、下载oracle 11g (11.2.0.1.0)1.1、Oracle Database 11.2.0.1.01.2、Oracle Database Grid Infrastructure 11.2.0.1.01.3、客户端 2、安装文档3、安装前准备3.1、建立用户和用户组3.2、sysctl3.3、security limits3.4、其他设置3.5、创建安装目录3.6、…