单链表的实现

CSDN主页:醋溜马桶圈_C语言进阶,初始C语言,数据结构-CSDN博客

Gitee主页:mnxcc (mnxcc) - Gitee.com

专栏:数据结构_醋溜马桶圈的博客-CSDN博客

目录

1.认识单链表

2.创建单链表

3.单链表的操作

3.1打印单链表

3.2开辟新空间

3.3尾插

3.4头插

3.5尾删

3.6头删

3.7查找

3.8在pos前面插入

3.9删除pos位置

3.10销毁

3.11在pos位置之后插入

 3.12删除pos位置之后的值

4.总代码

SList.h

SList.c

test.c


我们之前学习了顺序表的有关知识,顺序表存在下面的问题:

  • 尾插效率还不错,头插或中间插入删除,需要挪动数据,效率低
  • 满了以后只能扩容,扩容是有一定的消耗的,扩容一般存在一定的空间浪费

1.认识单链表

这篇文章我们来认识一下单链表

如果想要插入一个结点,就不需要挪动数据了,改指针的指向就可以了

同样我们删除结点,直接将前一个结点的指针指向后一个结点就可以了

首先我们还是从工程的角度去考虑,创建SList.h SList.c test.c三个文件

SList.h放置函数的声明

SList.c放置函数的定义

test.c进行测试 

2.创建单链表

3.单链表的操作

3.1打印单链表

//打印单链表
//尽量不要动phead
void SLTPrint(SLNode* phead)
{SLNode* cur = phead;while (cur != NULL){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}

3.2开辟新空间

//开辟新空间
SLNode* CreateNode(SLNDataType x)
{SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->val = x;newnode->next = NULL;return newnode;
}

3.3尾插

//尾插
void SLTPushBack(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}

3.4头插

//头插
void SLTPushFront(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = *pphead;*pphead = newnode;
}

3.5尾删

//尾删
void SLTPopBack(SLNode** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLNode* prev = NULL;SLNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}

3.6头删

//头删
void SLTPopFront(SLNode** pphead)
{assert(*pphead);SLNode* tmp = *pphead;*pphead = (*pphead)->next;free(tmp);
}

3.7查找

//查找
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{SLNode* cur = phead;while (cur){if (cur->val == x){return cur;}else{cur = cur->next;}}return NULL;
}

3.8在pos前面插入

//在pos前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{assert(pphead);assert(pos);assert(*pphead);//assert((!pos && !(*pphead)) || (pos && (*pphead)));if (*pphead == pos){SLTPushFront(pphead, x);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLNode* newnode = CreateNode(x);prev->next = newnode;newnode->next = pos;}
}

3.9删除pos位置

//删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos)
{assert(pphead);assert(pos);assert(*pphead);if (*pphead == pos){SLTPopFront(pphead);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}

3.10销毁

//销毁
void SLTDestroy(SLNode** pphead)
{assert(pphead);SLNode* cur = *pphead;while (cur->next != NULL){SLNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;
}

3.11在pos位置之后插入

// 单链表在pos位置之后插入x
void SLTInsertAfter(SLNode* pos, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = pos->next;pos->next = newnode;
}

 3.12删除pos位置之后的值

// 单链表删除pos位置之后的值
void SLTEraseAfter(SLNode* pos)
{assert(pos->next != NULL);pos->next = pos->next->next;free(pos->next);pos->next = NULL;
}

4.总代码

SList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//创建单链表
typedef int SLNDataType;
typedef struct SLNode
{SLNDataType val;struct SLNode* next;
}SLNode;//打印单链表
//尽量不要动phead
void SLTPrint(SLNode* phead);
//开辟新空间
SLNode* CreateNode(SLNDataType x);//尾插
void SLTPushBack(SLNode** pphead, SLNDataType x);
//头插
void SLTPushFront(SLNode** pphead, SLNDataType x);
//尾删
void SLTPopBack(SLNode** pphead);
//头删
void SLTPopFront(SLNode** pphead);//查找
SLNode* SLTFind(SLNode* phead, SLNDataType x);
//在pos前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x);
//删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos); // 单链表在pos位置之后插入x
void SLTInsertAfter(SLNode* pos, SLNDataType x);
// 单链表删除pos位置之后的值
void SLTEraseAfter(SLNode* pos);//销毁
void SLTDestroy(SLNode** pphead);

SList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"
//打印单链表
//尽量不要动phead
void SLTPrint(SLNode* phead)
{SLNode* cur = phead;while (cur != NULL){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}
//开辟新空间
SLNode* CreateNode(SLNDataType x)
{SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->val = x;newnode->next = NULL;return newnode;
}
//尾插
void SLTPushBack(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}
//头插
void SLTPushFront(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = *pphead;*pphead = newnode;
}
//尾删
void SLTPopBack(SLNode** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLNode* prev = NULL;SLNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}
//头删
void SLTPopFront(SLNode** pphead)
{assert(*pphead);SLNode* tmp = *pphead;*pphead = (*pphead)->next;free(tmp);
}
//查找
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{SLNode* cur = phead;while (cur){if (cur->val == x){return cur;}else{cur = cur->next;}}return NULL;
}
//在pos前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{assert(pphead);assert(pos);assert(*pphead);//assert((!pos && !(*pphead)) || (pos && (*pphead)));if (*pphead == pos){SLTPushFront(pphead, x);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLNode* newnode = CreateNode(x);prev->next = newnode;newnode->next = pos;}
}
//删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos)
{assert(pphead);assert(pos);assert(*pphead);if (*pphead == pos){SLTPopFront(pphead);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}
// 单链表在pos位置之后插入x
void SLTInsertAfter(SLNode* pos, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = pos->next;pos->next = newnode;
}
// 单链表删除pos位置之后的值
void SLTEraseAfter(SLNode* pos)
{assert(pos->next != NULL);pos->next = pos->next->next;free(pos->next);pos->next = NULL;
}
//销毁
void SLTDestroy(SLNode** pphead)
{assert(pphead);SLNode* cur = *pphead;while (cur->next != NULL){SLNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
int main()
{SLNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushFront(&plist, 5);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLNode* pos = SLTFind(plist, 2);SLTInsert(&plist, pos, 0);SLTPrint(plist);/*SLTErase(&plist, pos);SLTPrint(plist);*/SLTInsertAfter(pos, 0);SLTPrint(plist);SLTEraseAfter(pos);SLTPrint(plist);SLTDestroy(&plist);return 0;
}

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

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

相关文章

深入探讨Linux中的文本文件查看命令

目录 前言1 cat命令2 less命令3 more命令4 head命令5 tail命令6 总结 前言 在Linux系统中&#xff0c;文本文件是日常工作中不可或缺的一部分&#xff0c;无论是配置文件、日志文件还是代码文件&#xff0c;都需要用到文本文件查看命令。在本文中&#xff0c;我们将深入研究一…

AI创作系统ChatGPT源码+AI绘画系统+支持OpenAI DALL-E3文生图,可直接对话文生图

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。新增支…

桶装水订水小程序app,线上预约订水更便捷

桶装水订水小程序app&#xff0c;线上预约订水更便捷。设置好地址&#xff0c;一键订水&#xff0c;工作人员送水到家。还能配送新鲜果蔬&#xff0c;绿色健康有保证。送水软件手机版&#xff0c;提供各种品牌桶装水&#xff0c;在线发起订水服务&#xff0c;由服务人员送水到家…

QT windows与linux之间sokcet通信中文乱码问题解决方法

QT windows与linux之间sokcet通信中文乱码问题解决方法 linux发送与接收都转码utf-8: tcpClient ->write( send_msg.toUtf8());//解决乱码&#xff0c;发送转码 接收&#xff1a; QByteArray buffer tcpClient->readAll(); if(!buffer.isEmpty()) { // ui->plain…

双十一买高画质投影仪,当贝F6还是极米H6?

如果你想购买一台4K画质的投影仪,那么在各大平台搜索“双十一最值得买的4K投影仪”时,一定会注意到当贝F6和极米H6这两个型号投影仪。个人认为当贝F6和极米H6都分别是当贝和极米两个品牌非常具有性价比的4K投影仪。那么到底哪一台更适合你。 首先放一张参数对比图,方便参数控研…

登上CMMLU性能评测榜单第一 四大维度解码夸克自研大模型

11月14日&#xff0c;拥有千亿参数的夸克自研大模型正式发布&#xff0c;立刻占据CMMLU榜单第一名。夸克大模型将应用于通用搜索、医疗健康、教育学习、职场办公等多个场景。性能方面&#xff0c;其整体水平已经超过GPT-3.5&#xff0c;其中在写作、考试等部分场景中可以超过GP…

OpenCV实现手势虚拟拖拽

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下如何使用OpenCV实现手势虚拟拖拽&#xff0c;欢迎大家一起前来探讨学习~ 一、主要步骤及库的功能介绍 1.主要步骤 要实现本次实验&#xff0c;主要步骤如下&#xff1a; 导入OpenCV库。通过OpenCV读取摄…

做决策、定战略、带团队:顶级高手常用的16个思维模型

01 做决策 1.沃伦巴菲特的双目标清单系统&#xff08;Two-List System&#xff09; 弗林特当了巴菲特的私人飞行员十年之久&#xff0c;还曾为美国四任总统开过飞机&#xff0c;但他在事业上依然有更多追求。有一次&#xff0c;他和巴菲特在探讨他的职业生涯目标时&#xff0…

容器化nacos部署并实现服务发现(gradle)

1.如何容器化部署mysql 2. 如何容器化部署nacos 为不暴露我的服务器地址&#xff0c;本文全部使用localhost来代替服务器地址&#xff0c;所有的localhost都应该调整为你自己的服务器地址。 为不暴露我的服务器地址&#xff0c;本文全部使用localhost来代替服务器地址&#x…

Libra R-CNN: Towards Balanced Learning for Object Detection(2019.4)

文章目录 AbstractIntroduction引入问题1&#xff09; Sample level imbalance2) Feature level imbalance3) Objective level imbalance进行解决贡献 Related Work&#xff08;他人的work&#xff0c;捎带与我们的对比&#xff09;Model architectures for object detection&a…

突发!奥特曼宣布暂停ChatGPT Plus新用户注册!

大新闻&#xff01;就在刚刚&#xff01; OpenAI的CEO Sam Altman宣布暂停ChatGPT Plus 新用户注册&#xff01; Sam Altman对此解释道&#xff1a; 由于OpenAI开发日后ChatGPT使用量的激增超出了我们的承受能力&#xff0c;我们希望确保每个人都有良好的体验。 您仍然可以在a…

msvcp120.dll下载_msvcp120.dll文件丢失解决[dll系统文件修复]

msvcp120.dll是Microsoft Visual C库中的一个重要组件&#xff0c;属于Microsoft Visual C 2005 Redistributable Package。它提供了许多用于执行C程序所需的函数。Visual C是一款流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;广泛应用于游戏、视频和图形处理等领…

keepalived+haproxy配置集群和负载均衡

1、简介 1.1. Keepalived Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障。一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟IP,主服务器会发送特定的消息给备…

【PyQt小知识 - 2】:QTextEdit内容的更新和获取、隐藏或显示滚动条、光标插入文本、文本自适应移动

文章目录 QTextEdit更新和获取内容隐藏或显示滚动条光标插入文本文本自适应移动 QTextEdit 更新和获取内容 更新&#xff1a;QTextEdit().setText(text) 或 QTextEdit().setPlainText(text) 获取&#xff1a;QTextEdit().toPlainText() setText()和setPlainText()的区别&…

大文件分片上传、断点续传、秒传

小文件上传 后端&#xff1a;SpringBootJDK17 前端&#xff1a;JavaScriptsparkmd5.min.js 一、依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.2</ve…

1 Supervised Machine Learning Regression and Classification

文章目录 Week1OverViewSupervised LearningUnsupervised LearningLinear Regression ModelCost functionGradient Descent Week2Muliple FeatureVectorizationGradient Descent for Multiple RegressionFeature ScalingGradient DescentFeature EngineeringPolynomial Regress…

UE5 - UI Material Lab 学习笔记

1、学习资料收集 UI Material Lab : https://www.unrealengine.com/marketplace/zh-CN/product/ui-material-lab 视频1&#xff1a;https://www.bilibili.com/video/BV1Hm4y1t7Kn/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 视…

记录一次 添加脚本的记录+改错记录

1.Update 和 Delete 一定要记得where条件 update 表名称 set 字段1‘修改的值’ &#xff08;单引号&#xff09; where 字段‘’ and Aid‘’; update jxkh22 set JXKH2200001 ,JXKH2201002 where B003 and JXKH22034;delete from table_name where condition delete from …

Linux控制---进程程序替换

前言&#xff1a;前面我们学洗了Linux进程退出的相关知识&#xff0c;了解了什么是进程退出&#xff0c;已经进程等待的相关话题&#xff0c;今天&#xff0c;我们来学习Linux中的进程程序替换&#xff0c;进程程序替换在Linux中可以用于实现新程序的启动、程序升级、多进程程序…