当前位置: 首页 > news >正文

无头单向不循环链表和带头双向循环链表的创建

 Lei宝啊:个人主页

愿所有美好不期而遇



 

前言:

 

接下来我们将会了解最基础的链表--->单链表

以及最方便也是最爽的链表--->带头双向循环链表。

 

 若有看不懂之处,可画图或者借鉴这里:反转单链表,对于数据结构而言,无非就是增删查改,当我们能够熟练应用以及画图后,其OJ题和以下代码都是小卡拉米。

 

无头单向不循环链表

单链表图:

 

头文件:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int DataType;typedef struct STLNode
{DataType data;struct STLNode* next;
}STLNode;void STL_Print(STLNode* phead);
void STL_PushBack(STLNode** pphead, DataType x);
void STL_PushFront(STLNode** pphead, DataType x);
void STL_PopBack(STLNode** pphead);
void STL_PopFront(STLNode** pphead);
STLNode* STL_Find(STLNode* phead, DataType x);
void STL_InsertAfter(STLNode* pos, DataType x);
void STL_EraseAfter(STLNode* pos);
void STL_Destroy(STLNode** pphead);

Test文件:

#include "STLNode.h"void Test1(STLNode* phead);int main()
{STLNode* plist = NULL;Test1(plist);return 0;
}void Test1(STLNode* phead)
{STL_PushBack(&phead, 1);STL_PushBack(&phead, 2);STL_PushBack(&phead, 3);STL_Print(phead);STL_PushFront(&phead, 11);STL_PushFront(&phead, 22);STL_PushFront(&phead, 33);STL_Print(phead);STLNode* ret = STL_Find(phead, 1);STL_InsertAfter(ret, 666);STL_Print(phead);STL_EraseAfter(ret);STL_Print(phead);STL_Destroy(&phead);STL_Print(phead);//STL_PopBack(&phead);//STL_PopBack(&phead);//STL_Print(phead);//STL_PopFront(&phead);//STL_PopFront(&phead);//STL_Print(phead);}

函数源文件:

对于以下函数中部分有对phead和pphead的检查,部分没有,原因是这样的:

对于是否需要对其进行断言,我们是要看他为NULL时合不合理,合理就不断言,不合理就断言,例如STL_Printf函数中,当phead为NULL时,说明该链表是空的,直接打印NULL就可以,这是很合理的。而对于STL_PushBack函数来说,phead为NULL同样合理,因为phead为NULL我们尾插其实也就相当于头插,很合理,但是对于pphead来说,他作为plist的地址,就算plist为NULL,pphead是不应该为NULL的,所以他为NULL就非常不合理,我们要对其进行断言检查。

#include "STLNode.h"void STL_Print(STLNode* phead)
{while (phead){printf("%d->", phead->data);phead = phead->next;}printf("NULL\n");}STLNode* Malloc(DataType x)
{STLNode* temp = (STLNode*)malloc(sizeof(STLNode));if (temp == NULL){perror("malloc fail");exit(-1);}temp->data = x;temp->next = NULL;return temp;
}void STL_PushBack(STLNode** pphead, DataType x)
{assert(pphead);STLNode* temp = Malloc(x);if (*pphead == NULL){*pphead = temp;}else{STLNode* cur = *pphead;while (cur->next != NULL){cur = cur->next;}cur->next = temp;}
}void STL_PushFront(STLNode** pphead, DataType x)
{assert(pphead);STLNode* temp = Malloc(x);temp->next = *pphead;*pphead = temp;}void STL_PopBack(STLNode** pphead)
{assert(pphead);assert(*pphead);STLNode* cur = *pphead;STLNode* temp = *pphead;if (cur->next == NULL){free(cur);*pphead = NULL;}else{while (cur->next){temp = cur;cur = cur->next;}free(cur);temp->next = NULL;}}void STL_PopFront(STLNode** pphead)
{assert(pphead);assert(*pphead);STLNode* cur = *pphead;*pphead = (*pphead)->next;free(cur);}STLNode* STL_Find(STLNode* phead, DataType x)
{if (phead == NULL){printf("NULL\n");return;}while (phead != NULL){if (phead->data == x){return phead;}phead = phead->next;}printf("Can not find\n");return;
}void STL_InsertAfter(STLNode* pos, DataType x)
{assert(pos);STLNode* temp = Malloc(x);temp->next = pos->next;pos->next = temp;}void STL_EraseAfter(STLNode* pos)
{assert(pos);assert(pos->next);STLNode* cur = pos->next;pos->next = pos->next->next;free(cur);
}void STL_Destroy(STLNode** pphead)
{assert(pphead);if (*pphead == NULL){return;}STLNode* temp = *pphead;STLNode* cur = *pphead;while (temp){cur = temp->next;free(temp);temp = cur;}*pphead = NULL;
}



 

带头双向循环链表

图:

 

头文件:

这个链表最爽的地方在于,他可以很轻松地找到尾,不管是尾插还是头插都非常爽,非常方便,如果我们想在半小时内写完这个链表,那么就可以对尾插和头插复用LTInsert函数,对于尾删和头删复用LTErase函数,也就是说,这两个函数是核心函数,有了他们,迅速写完该链表成为现实。

尾插的复用:LTInsert(phead,x);

头插的复用:LTInsert(phead->next,x);

尾删的复用:LTErase(phead->prev);

头删的复用:LTErase(phead->next);

​​#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int DataType;typedef struct LTNode
{DataType data;struct LTNode* prev;struct LTNode* next;
}LTNode;LTNode* Init();
LTNode* Malloc(DataType x);
LTNode* LTFind(LTNode* phead, DataType x);
void LTPrintf(LTNode* phead);
void LTPushBack(LTNode* phead, DataType x);
void LTPopBack(LTNode* phead);
void LTPushFront(LTNode* phead, DataType x);
void LTPopFront(LTNode* phead);
void LTInsert(LTNode* pos, DataType x);   //在pos位置前插入节点
void LTErase(LTNode* pos);                //删除pos位置节点
void LTDestroy(LTNode* phead);

 Test文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include "LTNode.h"void Test1();int main()
{Test1();return 0;
}void Test1()
{LTNode* plist = NULL;plist = Init();LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPushBack(plist, 5);LTPushBack(plist, 6);LTPrintf(plist);LTPopBack(plist);LTPopBack(plist);LTPopBack(plist);LTPrintf(plist);LTPushFront(plist, 10);LTPushFront(plist, 20);LTPushFront(plist, 30);LTPrintf(plist);LTPopFront(plist);LTPrintf(plist);LTNode *pos = LTFind(plist, 10);LTInsert(pos, 66);LTPrintf(plist);LTErase(pos);LTPrintf(plist);LTDestroy(plist);plist = NULL;}

函数源文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include "LTNode.h"LTNode* Malloc(DataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;return newnode;
}LTNode* Init()
{LTNode* newnode = Malloc(0);newnode->next = newnode;newnode->prev = newnode;return newnode;
}void LTPrintf(LTNode* phead)
{assert(phead);printf("phead<=>");LTNode* cur = phead->next;while (cur != phead){printf("%d<=>", cur->data);cur = cur->next;}putchar('\n');
}void LTPushBack(LTNode* phead, DataType x)
{assert(phead);LTNode *newnode = Malloc(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;}void LTPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* tail = phead->prev;LTNode* newtail = tail->prev;newtail->next = phead;phead->prev = newtail;free(tail);
}void LTPushFront(LTNode* phead, DataType x)
{assert(phead);LTNode* newnode = Malloc(x);LTNode* old_next = phead->next;phead->next = newnode;newnode->prev = phead;newnode->next = old_next;old_next->prev = newnode;}void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* del = phead->next;phead->next = del->next;del->next->prev = phead;free(del);
}LTNode* LTFind(LTNode* phead, DataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x){return cur;}cur = cur->next;}printf("nothing!\n");return NULL;
}void LTInsert(LTNode* pos, DataType x)
{assert(pos);LTNode* newnode = Malloc(x);LTNode* posprev = pos->prev;posprev->next = newnode;newnode->prev = posprev;newnode->next = pos;pos->prev = newnode;
}void LTErase(LTNode* pos)
{assert(pos);LTNode* posprev = pos->prev;LTNode* posnext = pos->next;posprev->next = posnext;posnext->prev = posprev;free(pos);
}void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(cur);
}

 

相关文章:

无头单向不循环链表和带头双向循环链表的创建

Lei宝啊&#xff1a;个人主页 愿所有美好不期而遇 前言&#xff1a; 接下来我们将会了解最基础的链表--->单链表 以及最方便也是最爽的链表--->带头双向循环链表。 若有看不懂之处&#xff0c;可画图或者借鉴这里&#xff1a;反转单链表&#xff0c;对于数据结构而言&am…...

超简单的fastapi链接websocket用例

main.py from typing import Listfrom fastapi import FastAPI, WebSocket, WebSocketDisconnectapp FastAPI()class ConnectionManager:def __init__(self):# 存放激活的ws连接对象self.active_connections: List[WebSocket] []async def connect(self, ws: WebSocket):# 等…...

MySQL详解

目录 一、MySQL 概述二、MySQL 安装和配置三、MySQL 基础语法四、MySQL 高级语法五、MySQL 性能优化六、MySQL 应用场景和实例七、MySQL 开发工具和插件八、MySQL 学习资源和社区 一、MySQL 概述 MySQL 是一种开源的关系型数据库管理系统&#xff0c;最初由瑞典的 MySQL AB 公…...

Vue [Day2]

指令修饰符 v-model.trim v-model.number 事件名.stop click.stop 事件名.prevent keyup.enter <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-w…...

【前端|Javascript第1篇】一文搞懂Javascript的基本语法

欢迎来到JavaScript的奇妙世界&#xff01;作为前端开发的基石&#xff0c;JavaScript为网页增色不少&#xff0c;赋予了静态页面活力与交互性。如果你是一名前端小白&#xff0c;对编程一无所知&#xff0c;或者只是听说过JavaScript却从未涉足过&#xff0c;那么你来对了地方…...

【Linux命令200例】cp用于复制文件和目录(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…...

C高级_第二讲_shell指令和shell脚本_递归练习

思维导图 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位 int funh(int num){if(0 num){return 0;}else{funh(num/10);printf("%d\n", num%10);} }int main(int argc, const char *argv[]) {puts("请输入一个数");int num 0;scanf(&quo…...

静态路由综合实验

实验拓扑如下&#xff1a; 实验要求如下&#xff1a; 【1】R6为isp&#xff0c;接口IP地址均为公有地址;该设备只能配置IP地址&#xff0c;之后不能再对其进行任何配置 【2】R1~R5为局域网&#xff0c;私有IP地址192.168.1.0/24&#xff0c;请合理分配 【3】所有路由器上环回…...

Spring核心IOC控制反转思想-----Spring框架

import org.junit.Test;public class TestPublic {Testpublic void Test(){//控制反转是一种思想,是为了提高程序扩展力降低耦合度,达到DIP(Dependency Inversion Principle依赖倒置)原则//其核心是将对象的创建权交出去,由第三方容器负责管理,将对象和对象之间的维护权交出去,…...

中小企业如何做好MES管理系统实施建设

中小企业在生产制造领域面临着诸多挑战&#xff0c;包括提升产品竞争力、规范生产制造等。为了应对这些挑战&#xff0c;越来越多的中小企业开始实施MES生产管理系统。然而&#xff0c;由于企业规模小、资源实力不足等原因&#xff0c;很多企业在实施MES管理系统时存在一定的困…...

java环境搭建 Ubuntu Linux

jdk的安装和配置环境变量 使用apt sudo apt install default-jdk若是安装成功了在终端输入java -version来查看是否安装成功 使用官网下载的jdk包 直接在百度上搜索jdk&#xff0c;选择图片这个 网址:jdk下载网址 若是arm就选择带有arm的&#xff0c;反之选择x64的&#…...

微信小程序使用mp-html遇到的问题并解决

1、在本地配置寻找勾选使用npm 查了之后发现2023了 不需要勾选了 默认使用npm 2、在微信小程序编辑器左上角的 工具-->构建npm 然后就报错了 于是搜索到以下的内容&#xff1a; 没有找到可以构建的NPM包&#xff0c;请确认需要参与构建的npm都在 miniprogramRoot 目录内 -…...

【VTK】基于读取出来的 STL 模型,当用户点击鼠标左键时,程序将获取点击位置的点,显示其坐标,并设置它为模型的旋转原点

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 class PointPickedSignal : public QObjectclass MouseInteractorCommand : public vtkCommandvoid A::on_pushButtonSelected_clicked()void A::on…...

【第一阶段】kotlin的when表达式

1.Java 的if /when是语句 kotlin的if/when是表达式&#xff0c;表达式是有返回值的 java中void是个关键字&#xff0c;Unit在kotlin中是个类 2.当使用when语句的时候必须有一个不满足的值即else: fun main() {var week:Int5val info when(week){1->"今天是星期一"…...

C#中Convert.ToInt32() 和 int.Parse()的区别

都是用于将字符串转换为整数类型&#xff08;int&#xff09;的方法&#xff0c;但它们在处理转换过程中有一些区别&#xff1a; 1. 错误处理方式不同&#xff1a; - Convert.ToInt32()&#xff1a;如果字符串无法成功转换为整数类型&#xff0c;Convert.ToInt32()…...

安全学习DAY14_JS信息打点

信息打点——前端JS框架 文章目录 信息打点——前端JS框架小节概述-思维导图JS安全概述什么是JS渗透测试&#xff1f;前后端差异JS安全问题流行的Js框架如何判定JS开发应用&#xff1f; 测试方法&#xff08;JS文件的获取以及分析方法1、手工搜索分析2、半自动Burp分析插件介绍…...

windows下配置vue开发环境

安装nodejs&#xff0c;配置npm 1.下载安装包&#xff1a;下载地址&#xff1a;https://nodejs.org/en/download 2.安装node&#xff1a;下载完成后进行安装&#xff0c;记住安装的文件夹。本人安装路径为 D:\Program Files\nodejs 3.配置环境变量&#xff1a; ①安装完成后…...

AndroidTV 获取焦点View放大效果实现方式

需求 电视开发最常见的就是view获焦后要有放大效果&#xff0c;让用户明显看到。这里总结两个实现方法&#xff0c;以后遇到其他的再补充。 方式一&#xff1a;ViewCompat.animate(view) 1、注册焦点变化监听 mBtnFocus1.setOnFocusChangeListener(this);2、有焦点变化的时…...

访问者模式——操作复杂对象结构

1、简介 1.1、概述 访问者模式是一种较为复杂的行为型设计模式&#xff0c;它包含访问者和被访问元素两个主要组成部分。这些被访问的元素通常具有不同的类型&#xff0c;且不同的访问者可以对它们进行不同的访问操作。访问者模式使得用户可以在不修改现有系统的情况下扩展系…...

指针经典笔试题强训(附图详解)

目录 笔试题1&#xff1a; 解析&#xff1a; 运行结果&#xff1a; 笔试题2 解析&#xff1a; 运行结果&#xff1a; 笔试题3 解析&#xff1a; 运行结果&#xff1a; 笔试题4 解析&#xff1a; 运行结果&#xff1a; 笔试题5 解析&#xff1a; 运行结果&#xff1a;…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...