链表的实现

news/2025/2/2 0:52:21/

分两种方式实现,一种是双向链表,一种是双向循环链表。循环双向链表和双向链表的编码实现,差别很小,但是循环链表在效率上胜出很多,综合考虑,循环链表是首选。

完整工程代码:https://github.com/satadriver/dataStruct

头文件:

#pragma once#include "Element.h"#pragma pack(1)typedef struct  _LIST
{_LIST* prev;_LIST* next;ELEMENT* e;
}LIST;#pragma pack()class List {
public:List();~List();int insert(ELEMENT* e);int remove(ELEMENT* e);protected:LIST* search(ELEMENT* e);LIST* mList;int mSize;
};class CList {
public:CList();~CList();int insert(ELEMENT* e);int remove(ELEMENT* e);protected:LIST* search(ELEMENT* e);LIST* mList;int mSize;
};

循环双向链表实现代码如下:

CList::CList() {mList = 0;mSize = 0;
}CList::~CList() {if (mList){delete[] mList;mList = 0;}
}LIST* CList::search(ELEMENT* e) {LIST* list = mList;int cnt = 0;do{if (list == 0){break;}if (list->e->e == e->e){return list;}list = list->next;cnt++;} while (list != mList);return 0;
}int CList::insert(ELEMENT* e) {LIST* list = search(e);if (list){return 0;}list = new LIST;ELEMENT* e_new = new ELEMENT;memcpy(e_new, e, sizeof(ELEMENT));list->e = e_new;if (mList == 0){list->next = list;list->prev = list;mList = list;}else {LIST* prev = mList->prev;list->next = mList;list->prev = mList->prev;if (prev){prev->next = list;}mList->prev = list;}mSize++;return 1;
}int CList::remove(ELEMENT* e) {LIST* list = search(e);if (list == 0){return 0;}LIST* next = list->next;LIST* prev = list->prev;if (next){next->prev = prev;}if (prev){prev->next = next;}delete list->e;if (list == mList){if (mList->next == mList || mList->prev == mList){mList = 0;}else {mList = mList->next;}}delete list;int result = mSize;mSize--;return result;
}

双向链表实现代码:

List::List() {mList = 0;mSize = 0;
}List::~List() {if (mList){delete[] mList;mList = 0;}
}LIST* List::search(ELEMENT* e) {LIST* list = mList;int cnt = 0;while (list){if (list->e->e == e->e){return list;}list = list->next;cnt++;}return 0;
}int List::insert(ELEMENT* e) {LIST* list = search(e);if (list){return 0;}list = new LIST;ELEMENT* e_new = new ELEMENT;memcpy(e_new, e, sizeof(ELEMENT));list->e = e_new;int cnt = 0;if (mList == 0){list->next = 0;list->prev = 0;mList = list;cnt++;}else {LIST* tmp = mList;while (tmp->next){tmp = tmp->next;cnt++;}list->next = 0;list->prev = tmp;tmp->next = list;cnt++;}mSize = cnt;return cnt;
}int List::remove(ELEMENT* e) {LIST* list = search(e);if (list == 0){return 0;}LIST* next = list->next;LIST* prev = list->prev;if (next){next->prev = prev;}if (prev){prev->next = next;}delete list->e;if (list == mList){if (mList->next == 0){mList = 0;}else {mList = mList->next;}}delete list;int result = mSize;mSize--;return result;
}

http://www.ppmy.cn/news/1055528.html

相关文章

光谱成像系统视觉均匀校准积分球光源

数字相机的光谱灵敏度是成像传感器、光学透镜、滤光片以及相机内部图像处理过程等诸多因素的综合结果。即使是同一台相机,采用不同的光学镜头和不同的滤光片,由于光学系统的结构和光学材料的透过率不同,导致整个成像系统的光谱灵敏度也有所差…

SpringBoot 01 如何创建 和pom的解析

目录 1 Springboot的创建 步骤 2 项目的书写和运行 创建service包并在其下写一个service文件 项目的运行 pom文件的一些配置 parent web test 打包 打包过程 1 Springboot的创建 步骤 首先new一个新项目 然后依照如下创建 2 项目的书写和运行 创建service包并…

Jenkins的定时任务配置

jenkins配置定时任务位置(点击日程表的问好可查看语法配置) jenkins的定时任务的参数 # 定时任务参数(每个参数之间使用tab键或空格分隔)MINUTE HOUR DOM MONTH DOW 参数解释取值范围 MINUTE 分钟0-59HOUR小时0-23DOM一月的天数1-31MONTH月份1-12DOW 一周的天数0…

(2023)Linux安装pytorch并使用pycharm远程编译运行

(2023)Linux安装pytorch并使用pycharm远程编译运行 安装miniconda 这部分参考我这篇博客的前半部分Linux服务器上通过miniconda安装R(2022)_miniconda 安装r_Dream of Grass的博客-CSDN博客 创建环境 创建一个叫pytorch的环境…

iPhone 14 Pro 动态岛的功能和使用方法详解

当iPhone 14 Pro机型发布时,苹果公司将软件功能与屏幕顶部的药丸状切口创新集成,称之为“灵动岛”,这让许多人感到惊讶。这篇文章解释了它的功能、工作原理,以及你如何与它互动以执行动作。 一、什么是灵动岛?它是如何工作的 在谣言周期的早期‌iPhone 14 Pro‌ 在宣布时…

jdk 03.stream

01.集合处理数据的弊端 当我们在需要对集合中的元素进行操作的时候,除了必需的添加,删除,获取外,最典型的操作就是集合遍历 package com.bobo.jdk.stream; import java.util.ArrayList; import java.util.Arrays; import java.ut…

Linux编程:在程序中异步的调用其他程序

Linux编程:execv在程序中同步调用其他程序_风静如云的博客-CSDN博客 介绍了同步的调用其他程序的方法。 有的时候我们需要异步的调用其他程序,也就是不用等待其他程序的执行结果,尤其是如果其他程序是作为守护进程运行的,也无法等待其运行的结果。 //ssss程序 #include …

idea的断点调试

1、行断点 首先在代码的最左侧点击会显示红色的圆圈 第二步在main方法中右键选中debug run进行运行 会出现下面图片的情况 出现上图之后,点击console 下一步 这个时候就可以看到调试的结果了 6、方法调用栈:这里显示了该线程调试所经过的所有方法&…