c语言练习89:链表的使用
链表的使用
虽然有这么多的链表的结构,但是我们实际中最常⽤还是两种结构: 单链表 和 双向带头循环链表 1. ⽆头单向⾮循环链表:结构简单,⼀般不会单独⽤来存数据。实际中更多是作为其他数据结 构的⼦结构,如哈希桶、图的邻接表等等。另外这种结构在笔试⾯试中出现很多。 2. 带头双向循环链表:结构最复杂,⼀般⽤在单独存储数据。实际中使⽤的链表数据结构,都 是带头双向循环链表。另外这个结构虽然结构复杂,但是使⽤代码实现以后会发现结构会带 来很多优势,实现反⽽简单了,后⾯我们代码实现了就知道了。
补充说明:
1、链式机构在逻辑上是连续的,在物理结构上不⼀定连续
2、节点⼀般是从堆上申请的 3、从堆上申请来的空间,是按照⼀定策略分配出来的,每次申请的空间可能连续,可能不连续
SList.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//定义链表节点的结构
typedef int SLDataType;
typedef struct SListNode{int data;//要保存的数据struct SListNode* next;
}SLNode;
//创建节点组成链表并打印链表
void SLPrint(SLNode* phead);
//尾插
void SLPushBack(SLNode** pphead, SLDataType x);
void SLPushFront(SLNode** pphead, SLDataType x);
//尾删
void SLPopBack(SLNode** pphead);
void SLPopFront(SLNode** pphead);
//在指定位置之前插入数据
void SLInit(SLNode** pphead, SLNode* pos, SLDataType x);
//在指定位置之后插入数据
void SLInit(SLNode* pos, SLDataType x);
//找节点(考虑第一个参数为一级指针还是二级指针)
//因为不改变头节点,所以可以传一级指针
//但由于代码一致性原则(保持接口一致性),应该传二级指针
void SLFind(SLNode** pphead, SLDataType x);
//删除pos结点
void SLErase(SLNode** pphead, SLNode* pos);
//删除pos之后的结点
void SLEraseAfter(SLNode** pphead, SLNode* pos);
//销毁链表
void SLDesTory(SLNode** pphead);
SList.c
#define _CRT_SECURE_NO_WARNINGS
#include "SList.h"
void SLPrint(SLNode* phead) {//循环打印、SLNode* pcur = phead;while (pcur) {printf("%d ->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}SLNode* SLBuyNode(SLDataType x) {SLNode* node = (SLNode*)malloc(sizeof(SLNode));node->data = x;node->next = NULL;return node;
}
//尾插
void SLPushBack(SLNode** pphead, SLDataType x) {assert(pphead);SLNode* node = SLBuyNode(x);if (*pphead = NULL) {*pphead = node;return;}//链表不为空,找尾(定义一个临时变量pcur)SLNode* pcur= *pphead;while (pcur->next) {pcur = pcur->next;}pcur->next = node;
}
void SLPushFront(SLNode** pphead, SLDataType x) {assert(pphead);SLNode* node = SLBuyNode(x);//新节点跟头结点连接起来node->next = *pphead;//plist//让新的节点成为头结点*pphead = node;
}
void SLPopBack(SLNode** pphead) {assert(pphead);//第一个节点不能为空assert(*pphead);//只有一个节点的情况if ((*pphead)->next==NULL) {//直接删除头结点free(*pphead);pphead = NULL;return;}//有多个结点的情况//找到尾结点的前一个节点SLNode* prev = NULL;SLNode* ptail = *pphead;while (ptail->next != NULL) {prev = ptail;ptail = ptail->next;}//prev的next指针不在指向ptail,而是指向ptail的下一个节点prev->next = ptail->next;free(ptail);ptail = NULL;
}
void SLPopFront(SLNode** pphead) {assert(pphead);assert(*pphead);SLNode* del = *pphead;*pphead = (*pphead)->next;free(del);del = NULL;
}
void SLInit(SLNode** pphead, SLNode* pos, SLDataType x) {assert(pphead);SLNode* node = SLBuyNode(x);//处理没有结点的情况(约定链表不能为空+pos也不能为空)assert(pos);assert(*pphead);//处理只有一个结点+pos指向第一个结点(pos即为第一个结点)if ((*pphead)->next == NULL||pos==*pphead) {node->next = *pphead;*pphead = node;return;}//找pos的前一个节点SLNode* prev = *pphead;while (prev->next != NULL) {prev = prev->next;}prev->next = pos;pos->next = node;
}
//查找第一个为x的节点
void SLFind(SLNode** pphead, SLDataType x) {SLNode* pcur = *pphead;while (pcur) {if (pcur->data == x) {return pcur;}pcur = pcur->next;}return NULL;
}
//删除pos结点
void SLErase(SLNode** pphead, SLNode* pos) {assert(pphead);assert(*pphead);assert(pos);if (pos == *pphead) {*pphead = (*pphead)->next;free(pos);return;}//找pos的前一个节点SLNode* prev = *pphead;while (prev->next!=pos) {prev = prev->next;}prev->next = pos->next;free(pos);pos=NULL;
}
//删除pos之后的结点
void SLEraseAfter(SLNode** pphead, SLNode* pos) {assert(pos && pos->next);SLNode* del = pos->next;free(del);del = NULL;
}
//销毁链表
void SLDesTory(SLNode** pphead) {assert(pphead);SLNode* pcur = *pphead;//循环删除while (pcur) {SLNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS
//int removeElement(int* nums, int numsSize, int val) {
// int src, dst;
// while (src < numsSize) {
// if (nums[src] == val) {
// src++;
// }
// else {
// nums[dst] = nums[src];
// src++;
// dst++;
// }
// }
// return dst;
//}
//void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
// int l1 = m - 1, l2 = n - 1;
// int l3 = m + n - 1;
// while (l1 >= 0 && l2 >= 0) {
// if (nums1[l1] > nums2[l2]) {
// nums1[l3--] = nums1[l1--];
// }
// else {
// nums1[l3--] = nums2[l2--];
// }
// }
// while (l2 >= 0) {
// nums1[l3--] = nums2[l2--];
// }
//}
#include"SList.h"
void slttest() {SLNode* node1 = (SLNode*)malloc(sizeof(SLNode));node1->data = 1;SLNode* node2 = (SLNode*)malloc(sizeof(SLNode));node2->data = 2;SLNode* node3 = (SLNode*)malloc(sizeof(SLNode));node3->data = 3;SLNode* node4 = (SLNode*)malloc(sizeof(SLNode));node4->data = 4;node1->next = node2;node2->next = node3;node3->next = node4;node4->next = NULL;SLNode* plist = node1;SLPrint(plist);
}
int main() {slttest();return 0;
}
相关文章:

c语言练习89:链表的使用
链表的使用 虽然有这么多的链表的结构,但是我们实际中最常⽤还是两种结构: 单链表 和 双向带头循环链表 1. ⽆头单向⾮循环链表:结构简单,⼀般不会单独⽤来存数据。实际中更多是作为其他数据结 构的⼦结构,如哈希桶、…...

ArkTS及openHarmony
补充 padding:内边距,也就是盒子边和盒子内部的距离 margin:外边距,也就是盒子和盒子的距离 openHarmony应用开发及UI界面 常用布局 Row 水平线性布局核心代码 子控件会共享同一行,也就是都在同一行内 Preview C…...

Idea怎么配置Maven才能优先从本地仓库获取依赖
网上的方法 : 在设置中搜索 Runner ,在VM Option中设置参数 -DarchetypeCataloginternal删除 解压后的依赖包中的 _remote.repositories m2e-lastUpdated.properties *.lastUpdated 文件。 上边都没有效果 最终的解决方法,修改maven配置文件settings.xml 主要两个…...
聊聊HttpClient的DnsResolver
序 本文主要研究一下HttpClient的DnsResolver DnsResolver org/apache/http/conn/DnsResolver.java /*** Users may implement this interface to override the normal DNS lookup offered* by the OS.** since 4.2*/ public interface DnsResolver {/*** Returns the IP a…...

剑指智能驾驶,智己LS6胜算几何?
监制 | 何玺 排版 | 叶媛 10月12日,IM智己旗下的新车智己LS6宣布上市。 新车型搭载尖端科技多项,其中以“全画幅数字驾舱屏”、和城市高阶智能辅助驾驶为核心的智驾技术,更是引来众多用户关注。 01 新能源新卷王智己LS6 智己LS6一发布就…...

网络工程师知识点5
71、什么是FTP? FTP是文件传输协议。 FTP传输数据时支持两种传输模式:ASCII模式和二进制模式。 需要TCP的21号端口来建立控制连接 需要TCP的20号端口来建立数据连接 72、什么是telnet? Telnet提供了一个交互式操作界面,允许终端远…...
未来展望:大型语言模型与 SQL 数据库集成的前景与挑战
一、前言 随着 GPT-3、PaLM 和 Anthropic 的 Claude 等大型语言模型 (LLM) 的出现引发了自然语言在人工智能领域的一场革命。这些模型可以理解复杂的语言、推理概念并生成连贯的文本。这使得各种应用程序都能够使用对话界面。然而,绝大多数企业数据都存储在结构化 …...

SpringCloud-Hystrix
一、介绍 (1)避免单个服务出现故障导致整个应用崩溃。 (2)服务降级:服务超时、服务异常、服务宕机时,执行定义好的方法。(做别的) (3)服务熔断:达…...

Ansible脚本进阶---playbook
目录 一、playbooks的组成 二、案例 2.1 在webservers主机组中执行一系列任务,包括禁用SELinux、停止防火墙服务、安装httpd软件包、复制配置文件和启动httpd服务。 2.2 在名为dbservers的主机组中创建一个用户组(mysql)和一个用户&#x…...
pytorch 模型部署之Libtorch
Python端生成pt模型文件 net.load(model_path) net.eval() net.to("cuda")example_input torch.rand(1, 3, 240, 320).to("cuda") traced_model torch.jit.trace(net, example_input) traced_model.save("model.pt")output traced_model(exa…...

Unity——数据存储的几种方式
一、PlayerPrefs PlayerPrefs适合用于存储简单的键值对数据 存储的数据会在游戏关闭后依然保持,并且可以在不同场景之间共享,适合用于需要在游戏不同场景之间传递和保持的数据。 它利用key-value的方式将数据保存到本地,跟字典类似。然后通…...
『heqingchun-ubuntu系统下安装cuda与cudnn』
ubuntu系统下安装cuda与cudnn 一、安装依赖 1.更新 sudo apt updatesudo apt upgrade -y2.基础工具 sudo apt install -y build-essential python二、安装CUDA 1.文件下载 网址 https://developer.nvidia.com/cuda-toolkit-archive依次点击 (1)“CUDA Toolkit 11.6.2”…...

Unity AI Muse 基础教程
Unity AI Muse 基础教程 Unity AI 内测资格申请Unity 项目Package ManagerMuse Sprite 安装Muse Texture 安装 Muse Sprite 基础教程什么是 Muse Sprite打开 Muse Sprite 窗口Muse Sprite 窗口 参数Muse Sprite Generations 窗口 参数Muse Sprite Generations 窗口 画笔Muse Sp…...

pgsl基于docker的安装
1. 有可用的docker环境 ,如果还没有安装docker,则请先安装docker 2. 创建pg数据库的挂载目录 mkdir postgres 3. 下载pg包 docker pull postgres 这个命令下载的是最新的pg包,如果要指定版本的话,则可以通过在后面拼接 :versio…...
idea设置某个文件修改后所在父文件夹变蓝色
idea设置某个文件修改后所在父文件夹变蓝色的方法: 老版idea设置方法: File---->Settings---->Version Control---->勾选 Show directories with changed descendants 新版idea设置方法: File---->Settings---->Version Co…...
代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离
代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离 一、583. 两个字符串的删除操作 题目链接:https://leetcode.cn/problems/delete-operation-for-two-strings/ 思路:定义dp[i][j]为要是得区间[0,i-1]和区间[0,j-1]所需要删除…...

秋日有感之秋诉-于光
诗:于光 秋风扫叶枝不舍, 叶落随风根欢唱。 秋日穿云不入眼, 云亦婆娑诉余年。...
ubuntu 22.04版本修改服务器名、ip,dns信息的操作方法
总结 1、ubuntu修改服务器名重启后生效的方法是直接修改/etc/hostname文件 2、ubuntu 22.04操作系统配置ip和dns信息,一般只需要使用netplan命令行工具来配置就行,在/etc/netplan/在目录下创建一个yaml文件就可以实现ip和dns的配置,当然如果…...

【微信小程序】6天精准入门(第2天:小程序的视图层、逻辑层、事件系统及页面生命周期)
一、视图层 View 1、什么是视图层 框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。WXML(WeiXin Markup language) 用于描述页面的结构。WXS(WeiXin Script) 是小程序的一套脚本语言&am…...

速学Linux丨一文带你打开Linux学习之门
前言 如果你是刚开始学习Linux的小白同学,相信你已经体会到与学习一门编程语言相比,学习Linux系统的门槛相对较高,你会遇到一些困惑,比如: 为什么要学习Linux,学成之后我们可以在哪些领域大显身手…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...