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

数据结构基础(带头节点的双向循环链表)

完整代码

      • DLinkList.h
      • DLinkList.c
      • test.c

DLinkList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int ElemType;// SList - 单链表
// DList - 双链表
// 带头节点的双向循环链表 - 最优链表结构,任意位置插入、删除数据,时间复杂度O(1)
typedef struct ListNode{struct ListNode* prev;struct ListNode* next;ElemType data;
}ListNode;// 初始化
ListNode* ListInit();
// 打印
void ListPrint(ListNode* phead);
// 销毁
void ListDestory(ListNode* phead);
// 尾插
void ListPushBack(ListNode* phead, ElemType x);
// 头产
void ListPushFront(ListNode* phead, ElemType x);
// 尾删
void ListPopBack(ListNode* phead);
// 头删
void ListPopFront(ListNode* phead);// 查找节点的pos位置
ListNode* ListFind(ListNode* phead, ElemType x);
// 在pos位置前插入
void ListInsert(ListNode* pos, ElemType x);
// 删除pos位置的值
void ListErase(ListNode* pos);

DLinkList.c

#define _CRT_SECURE_NO_WARNINGS 1#include "DList.h"// 返回节点(头节点、要插入的节点)
ListNode* BuyListNode(ElemType x)
{ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));newNode->data = x;newNode->prev = NULL;newNode->next = NULL;return newNode;
}
// 初始化
ListNode* ListInit()
{ListNode* phead = BuyListNode(0);// 申请头节点,数据域传0phead->next = phead;phead->prev = phead;return phead;
}
// 打印
void ListPrint(ListNode* phead)
{assert(phead);ListNode* cur = phead->next;while (cur != phead){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}
// 销毁
void ListDestory(ListNode* phead)
{assert(phead);ListNode* cur = phead->next;while (cur != phead){ListNode* next = cur->next;// 先找到要删节点的下一个节点free(cur);cur = next;}free(phead);phead = NULL;
}
// 尾插(直接调用Insert(在pos位置前插入))
void ListPushBack(ListNode* phead, ElemType x)
{assert(phead);// 头节点不为空//ListNode* newNode = BuyListNode(x); 带头的双向循环链表不考虑没有节点,有节点的情况//ListNode* tail = phead->prev;// 定义一个尾指针,指向头节点的前驱 画图分析//tail->next = newNode;//newNode->prev = tail;//newNode->next = phead;//phead->prev = newNode;ListInsert(phead, x);}
// 头插(直接调用Insert(在pos位置前插入))
void ListPushFront(ListNode* phead, ElemType x)
{assert(phead); 没有节点也不会有问题//ListNode* first = phead->next;//ListNode* newNode = BuyListNode(x);//phead->next = newNode;//newNode->prev = phead;//newNode->next = first;//first->prev = newNode;ListInsert(phead->next, x);}// 头删(可以调用Erase)
void ListPopFront(ListNode* phead)
{//assert(phead);//assert(phead->next != phead);// 链表没有一个节点//ListNode* first = phead->next;//ListNode* second = first->next;//phead->next = second;//second->prev = phead;//free(first);//first = NULL;ListErase(phead->next);
}
// 尾删(可以调用Erase)
void ListPopBack(ListNode* phead)
{//assert(phead);//assert(phead->next != phead);// 链表没有一个节点//ListNode* tail = phead->prev;//ListNode* prev = tail->prev;//prev->next = phead;//phead->prev = prev;//free(tail);//tail = NULL;ListErase(phead->prev);
}// 查找节点的pos位置
ListNode* ListFind(ListNode* phead, ElemType x)
{assert(phead);ListNode* cur = phead->next;while (cur != phead){if (cur->data == x)return cur;cur = cur->next;}return NULL;
}
// 在pos位置(前!!!)插入
void ListInsert(ListNode* pos, ElemType x)
{assert(pos);ListNode* prev = pos->prev;ListNode* newNode = BuyListNode(x);prev->next = newNode;newNode->prev = prev;newNode->next = pos;pos->prev = newNode;
}
// 删除pos位置的值
void ListErase(ListNode* pos)
{ListNode* prev = pos->prev;ListNode* next = pos->next;prev->next = next;next->prev = prev;free(pos);pos = NULL;}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"void testList1()
{ListNode* plist = ListInit();ListPushBack(plist, 1);ListPushBack(plist, 2);ListPushBack(plist, 3);ListPushBack(plist, 4);ListPrint(plist);ListPushFront(plist, 0);ListPushFront(plist, -1);ListPrint(plist);ListPopFront(plist);ListPrint(plist);ListPopBack(plist);ListPrint(plist);ListDestory(plist);
}
void testList2()
{ListNode* plist = ListInit();ListPushBack(plist, 1);ListPushBack(plist, 2);ListPushBack(plist, 3);ListPushBack(plist, 4);ListPrint(plist);ListNode* pos = ListFind(plist, 2);if (pos){pos->data *= 10;printf("找到了,并且乘10\n");}elseprintf("没有找到\n");ListPrint(plist);ListInsert(pos, 300);ListPrint(plist);ListErase(pos);ListPrint(plist);
}
int main()
{testList1();return 0;
}

相关文章:

数据结构基础(带头节点的双向循环链表)

完整代码 DLinkList.hDLinkList.ctest.c DLinkList.h #pragma once #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int ElemType;// SList - 单链表 // DList - 双链表 // 带头节点的双向循环链表 - 最优链表结构&#xff0c;任意位置…...

STM32CubeMx+MATLAB Simulink点灯程序

STM32CubeMxMATLAB点灯程序 ✨要想实现在MATLAB Simulink环境下使用STM32&#xff0c;前提是已经搭建好MATLAB环境并且安装了必要的Simulink插件&#xff0c;以及对应的STM32支持包。 &#x1f33f;需要准备一块所安装支持包支持的STM32开发板. &#x1f516;具体支持包详情页…...

【深度学习】gan网络原理生成对抗网络

【深度学习】gan网络原理生成对抗网络 GAN的基本思想源自博弈论你的二人零和博弈&#xff0c;由一个生成器和一个判别器构成&#xff0c;通过对抗学习的方式训练&#xff0c;目的是估测数据样本的潜在分布并生成新的数据样本。 1.下载数据并对数据进行规范 transform tran…...

springboot参数汇总

multipart multipart.enabled 开启上传支持&#xff08;默认&#xff1a;true&#xff09; multipart.file-size-threshold: 大于该值的文件会被写到磁盘上 multipart.location 上传文件存放位置 multipart.max-file-size最大文件大小 multipart.max-request-size 最大请求…...

【算法刷题】Day9

文章目录 611. 有效三角形的个数题干&#xff1a;题解&#xff1a;代码&#xff1a; LCR 179. 查找总价格为目标值的两个商品题干&#xff1a;题解&#xff1a;代码&#xff1a; 1137. 第 N 个泰波那契数题干&#xff1a;原理&#xff1a;1、状态表示&#xff08;dp表里面的值所…...

LangChain的函数,工具和代理(三):LangChain中轻松实现OpenAI函数调用

在我之前写的两篇博客中:OpenAI的函数调用,LangChain的表达式语言(LCEL)中介绍了如何利用openai的api来实现函数调用功能&#xff0c;以及在langchain中如何实现openai的函数调用功能&#xff0c;在这两篇博客中&#xff0c;我们都需要手动去创建一个结构比较复杂的函数描述变量…...

WiFi概念介绍

WiFi概念介绍 1. 什么是WLAN2. 什么是Wi-Fi3. Wi-Fi联盟4. WLAN定义范围5. WiFi协议体系6. 协议架构7. WiFi技术的发展7.1 IEEE802.117.2 802.11标准和补充 8. 术语 1. 什么是WLAN Wireless Local Area Network&#xff0c;采用802.11无线技术进行互连的一组计算机和相关设备。…...

如何优雅的进行业务分层

1.什么是应用分层 说起应用分层&#xff0c;大部分人都会认为这个不是很简单嘛 就controller&#xff0c;service, mapper三层。 看起来简单&#xff0c;很多人其实并没有把他们职责划分开&#xff0c;在很多代码中&#xff0c;controller做的逻辑比service还多,service往往当…...

C++的std命名空间

总以为自己懂了&#xff0c;可是仔细想想&#xff0c;多问自己几个问题&#xff0c;发现好像又不是很清楚 命名空间&#xff08;Namespace&#xff09;是C中一种用于解决命名冲突问题的机制&#xff0c;它能够将全局作用域划分为若干个不同的区域&#xff0c;每个区域内可以有…...

unity学习笔记

一、射线检测 如何让鼠标点击某个位置&#xff0c;游戏角色就能移动到该位置&#xff1f; 实现的原理分析&#xff1a;我们能看见游戏的东西就是摄像机拍摄到的东西&#xff0c;所以摄像机的镜平面就是当前能看到的了。 那接下来我们可以让摄像机发射一条射线&#xff0c;鼠标…...

使用SpringBoot和ZXing实现二维码生成与解析

一、ZXing简介 ZXing是一个开源的&#xff0c;用Java实现的多种格式的1D/2D条码图像处理库。它包含了用于解析多种格式的1D/2D条形码的工具类&#xff0c;目标是能够对QR编码&#xff0c;Data Matrix, UPC的1D条形码进行解码。在二维码编制上&#xff0c;ZXing巧妙地利用构成计…...

C++模板—函数模板、类模板

目录 一、函数模板 1、概念 2、格式 3、实例化 4、模板参数的匹配 二、类模板 1、定义格式 2、实例化 交换两个变量的值&#xff0c;针对不同类型&#xff0c;我们可以使用函数重载实现。 void Swap(double& left, double& right) {double tmp left;left ri…...

Monkey

一、Monkey的概念 “猴子测试”是指没有测试经验的人甚至对计算机根本不了解的人&#xff08;就像猴子一样&#xff09;不需要知道程序的任何用户交互方面的知识&#xff0c;如果给他一个程序&#xff0c;他就会针对他看到的界面进行操作&#xff0c;其操作是无目的的、乱点乱按…...

SQL中left join、right join、inner join等的区别

一张图可以简洁明了的理解出left join、right join、join、inner join的区别&#xff1a; 1、left join 就是“左连接”&#xff0c;表1左连接表2&#xff0c;以左为主&#xff0c;表示以表1为主&#xff0c;关联上表2的数据&#xff0c;查出来的结果显示左边的所有数据&#…...

算法学习—排序

排序算法 一、选择排序 1.算法简介 选择排序是一个简单直观的排序方法&#xff0c;它的工作原理很简单&#xff0c;首先从未排序序列中找到最大的元素&#xff0c;放到已排序序列的末尾&#xff0c;重复上述步骤&#xff0c;直到所有元素排序完毕。 2.算法描述 1&#xff…...

在Pycharm中创建项目新环境,安装Pytorch

在python项目中&#xff0c;很多项目使用的各类包的版本是不一致的。所以我们可以对每个项目有专属于它的环境。所以这个文章就是教你如何创建新环境。 一、创建新环境 首先我们需要去官网下载conda。然后在Pycharm下面添加conda的可执行文件。 用conda创建新环境。 二、…...

linux里source、sh、bash、./有什么区别

1、source source a.sh 在当前shell内去读取、执行a.sh&#xff0c;而a.sh不需要有"执行权限" source命令可以简写为"." . a.sh 注意&#xff1a;中间是有空格的。 2、sh/bash sh a.sh bash a.sh 都是打开一个subshell去读取、执行a.sh&#xff0c;而a.…...

IDEA编译器技巧-提示词忽略大小写

IDEA编译器技巧-提示词忽略大小写 写代码时,每次创建对象都要按住 Shift 字母 做大写开头, 废手, 下面通过编译器配置解放Shift 键 setting -> Editor -> General -> Code Completion -> Match case 把这个√去掉, 创建对象就不需要再按住 Shift 键 示例: 1.…...

【MySQL】MySQL安装 环境初始化

MySQL安装 MYSQL官网 安装完成后,傻瓜下一步即可 配置一下环境变量即可 (1) 初始化MySQL, 管理员身份运行 mysqld --initialize-insecure(2) 注册 mysqld mysqld -install# 如果记录以前的版本执行下面指令 mysqld -remove(3) 启动MySQL服务 // 启动mysql服务 net start …...

C# IList 与List区别二叉树的层序遍历

IList 接口&#xff1a; IList 是一个接口&#xff0c;定义了一种有序集合的通用 API。继承自 ICollection 接口和IEnumerable<T>&#xff0c;是所有泛型列表的基接&#xff0c;口它提供了对列表中元素的基本操作&#xff0c;如添加、删除、索引访问等。IList 不是一个具…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...