数据结构之自定义双链表

Python数据结构——链表 链表是一种基本的数据结构,用于组织和管理数据。在Python中,你可以使用自定义类来实现链表。了解链表数据结构及其应用场景将帮助你更好地解决各种编程问题。链表是动态分配内存的数据结构,因此非常适合实现动态数据结构和一些高级算法。无论是在数据结构设计、算法实现还是操作系统开发中,链表都是一个非常有用的工具。 阅读详情

顾名思义:双链表就是在数据域之内还保存了直接前驱和直接后继, 除头尾节点除外, 这种双链表的优点是插入和删除花费的时间为O(1)

package link;

/*
 * 双链表
 */
public class MyLinkedList<AnyType> implements Iterable<AnyType>{

    private int theSize;    //除去头尾节点之外的大小(数据的大小)
    private int modCount = 0;
    private Node<AnyType> beginMarker;  // 头节点
    private Node<AnyType> endMarker;    //尾节点

    /*
     * @功能  从内存中开辟一个节点并且插入到链表中
     * @data    数据域
     * @prev    保存前一个节点的地址(指针)
     * @next    保存后一个节点的地址
     */
    private static class Node<AnyType>{
        public AnyType data;
        public Node<AnyType> prev;  
        public Node<AnyType> next;  
        //构造方法
        public Node(AnyType d, Node<AnyType> p, Node<AnyType> n){
            this.data = d;
            this.prev = p;
            this.next = n;
        }
    }

    /*
     * 构造方法
     */
    public MyLinkedList(){
        doClear();
    }

    /*
     * @功能: 清除数据
     */
    public void clear(){
        doClear();
    }

    /*
     * @beginMarker 头节点,在初始化的时候next没有指向尾节点,因为在初始化时比尾节点先初始化,所以只能等尾节点初始化完成之后才能指向尾节点
     * @endMarker   尾节点,在初始化的时候它是指向头节点的
     * @theSize     初始化或清空的长度必须为0
     */
    private void doClear(){
        beginMarker = new Node<AnyType>(null, null, null);
        endMarker = new Node<AnyType>(null, beginMarker, null);
        beginMarker.next = endMarker;

        theSize = 0;
        modCount++;
    }

    /*
     * @theSize 返回双链表的大小
     */
    public int size(){
        return theSize;
    }

    /*
     * @功能  判断是否是空
     */
    public boolean isEmpty(){
        return size() == 0;
    }

    /*
     * @功能  直接从尾部添加元素
     * size 返回数组的大小
     * x    保存的数据
     */
    public boolean add(AnyType x){
        add(size(), x);
        return true;
    }

    /*
     * @idx size()的大小,从最后插入
     * @x   要插入元素的内容
     */
    public void add(int idx, AnyType x){
        addBefore(getNode(idx, 0, size()), x);
    }

    public void addFirst(AnyType x){
        addBefore(beginMarker.next, x);
    }

    public void addLast(AnyType x){
        addBefore(endMarker.prev, x);
    }


    private Node<AnyType> getNode(int idx){
        return getNode(idx, 0, size());
    }


    /*
     * 查找链表中是否存在这个元素
     */
    public boolean contains(AnyType x){
        Node<AnyType> node = beginMarker;

        while(node != endMarker && !(node.data.equals(x))){
            node = node.next;
        }
        return (node != endMarker);
    }
    /*
     * @功能  找到要添加的位置
     *      假如要是从指定位置插入的话,为了减少时间,当插入的位置在前半部分的时候默认是从头节点开始找位置,
     *      假如要插入的位置是在后半部分的时候是从尾节点开始找插入位置
     */
    private Node<AnyType> getNode(int idx, int lower, int upper){
        Node<AnyType> p;

        if(idx < lower || idx > upper)
            throw new IndexOutOfBoundsException();

        if(idx < size()/2){
            p = beginMarker.next;
            for(int i=0; i<idx; i++)
                p = p.next;
        }else{
            p = endMarker;
            for(int i=size(); i>idx; i--)
                p = p.prev;
        }

        return p;
    }

    /*
     * @功能  将节点插入到要插入的位置
     * 第一步: 你的节点已经存好了你指向的前驱以及后继
     * 第二步: 将你的前驱指向自己
     * 第三部: 将你的后继指向自己
     */
    private void addBefore(Node<AnyType> p, AnyType x){
        Node<AnyType> newNode = new Node<AnyType>(x, p.prev, p);
        newNode.prev.next = newNode;
        p.prev = newNode;
        theSize++;
        modCount++;
    }

    /*
     * @功能查找相应位置的元素 不过这种查找速度太慢
     */
    public AnyType get(int idx){
        return getNode(idx).data;
    }

    /*
     * @    获取第一项的值
     */
    public AnyType getFirst(){
        return getNode(0).data;
    }

    /*
     * @功能  获取最后一项的值
     */
    public AnyType getLast(){
        return getNode(size()-1).data;
    }

    /*
     * 按照下表来更改链表中的元素
     */
    public AnyType set(int idx, AnyType x){
        Node<AnyType> p =  getNode(idx);
        AnyType old = p.data;
        p.data = x;
        return old;
    }

    /*
     * 按照节点来更改集合中的元素
     */
    public AnyType set(Node<AnyType> n, AnyType x){
        AnyType old = n.data;
        n.data = x;
        return old;
    }

    /*
     * 按照下标来进行删除操作
     */
    public AnyType remove(int idx){
        return remove(getNode(idx));    
    }

    /*
     * 迭代器里面的删除操作来进行
     */
    private AnyType remove(Node<AnyType> p){
        p.prev.next = p.next;
        p.next.prev = p.prev;
        theSize--;
        modCount++;
        return p.data;
    }

    /*
     * @功能  删除第一项
     */
    public AnyType removeFirst(){
        return remove(beginMarker.next);
    }

    /*
     * @功能  删除最后一项
     */
    public AnyType removeLast(){
        return remove(endMarker.prev);
    }

    @Override
    public java.util.Iterator<AnyType> iterator() {
        return new LinkedListIterable();
    }

    public java.util.ListIterator<AnyType> listIterator(){
        return new MyLingedListlistIterator();
    }
    /*
     * 迭代器
     */
    private class LinkedListIterable implements java.util.Iterator<AnyType>{

        private Node<AnyType> current = beginMarker.next;
        private int expectModCount = modCount;
        private boolean okToRemove = false;
        @Override
        public boolean hasNext() {
            return current != endMarker;
        }

        @Override
        public AnyType next() {
            if(modCount != expectModCount){
                throw new java.util.ConcurrentModificationException();
            }
            if(!hasNext()){
                throw new IllegalStateException();
            }
            AnyType nextItem = current.data;
            current = current.next;
            okToRemove = true;
            return nextItem;
        }

        public void remove(){
            if(modCount != expectModCount)
                throw new java.util.ConcurrentModificationException();
            if(!okToRemove){
                throw new IllegalStateException();
            }

            MyLinkedList.this.remove(current.prev);
            expectModCount++;
            okToRemove = false;
        }
    }

    private class MyLingedListlistIterator implements java.util.ListIterator<AnyType>{
        private Node<AnyType> node = beginMarker;
        private int expectModeCount = modCount;
        boolean bool = false;
        @Override
        public boolean hasNext() {
            // TODO 自动生成的方法存根
            return node != endMarker;
        }

        @Override
        public AnyType next() {
            if(expectModeCount != modCount)
                throw new   java.util.ConcurrentModificationException(); 
            if(!hasNext())
                throw new java.util.NoSuchElementException();

            AnyType nextItem = node.data;
            node = node.next;
            bool = true;
            expectModeCount++;

            return nextItem;
        }

        @Override
        public boolean hasPrevious() {
            // TODO 自动生成的方法存根
            return node.prev != beginMarker;
        }

        @Override
        public AnyType previous() {
            if(expectModeCount != modCount)
                throw new java.util.ConcurrentModificationException();
            if(!hasPrevious())
                throw new java.util.NoSuchElementException();

            node = node.prev;
            AnyType prve = node.data;
            bool = true;

            return prve;
        }

        @Override
        public int nextIndex() {
            throw new java.lang.UnsupportedOperationException();
        }

        @Override
        public int previousIndex() {
            throw new java.lang.UnsupportedOperationException();
        }

        @Override
        public void remove() {
            if(expectModeCount != modCount)
                throw new java.util.ConcurrentModificationException();
            if(!bool)
                throw new IllegalStateException();

            MyLinkedList.this.remove(node.prev);
            bool = false;
        }

        @Override
        public void set(AnyType e) {
            if(expectModeCount != modCount)
                throw new java.util.ConcurrentModificationException();
            MyLinkedList.this.set(node.next, e);
        }

        @Override
        public void add(AnyType e) {
            if(expectModeCount != modCount)
                throw new java.util.ConcurrentModificationException();
            MyLinkedList.this.addBefore(node.next, e);
        }

    }
}
win11禁止更新,草履虫教程 本文介绍了彻底禁止Windows 11系统更新的组合方法,包括禁用核心服务、修改注册表、关闭计划任务和使用组策略(专业版适用)。作者特别提醒,禁止更新会影响系统安全性,建议实体机保持更新,仅虚拟机等特殊情况下使用这些方法。同时强调即使禁用更新,也应定期手动检查重要安全补丁。文章最后附上了作者的个人网站信息。 阅读详情

相关推荐

使用STM32微控制器实现光电传感器的接口和数据处理

本文将介绍如何使用STM32微控制器实现光电传感器的接口和数据处理的方案,包括硬件设计、引脚配置、数据采集、滤波和阈值判断等关键步骤,并给出相应的代码示例。本文将介绍如何使用STM32微控制器实现光电传感器的接口和数据处理的方案,包括硬件设计、引脚配置、数据采集、滤波和阈值判断等关键步骤,并给出相应的代码示例。在光电传感器的接口和数据处理的实现过程中,要关注系统的性能。在使用STM32微控制器实现光电传感器的接口和数据处理之前,需要设计一个合适的硬件平台。

weixin_66608063的博客 3199

数据结构+算法连载六 无序-双向链表

单向链表,查找的方向只能是一个方向,而双向链 表可以向前或者向后查找。 单向链表不能自我删除,需要靠辅助节点 ,而双向 链表,则可以自我删除,所以前面我们单链表删除 时节点,总是找到temp,temp是待删除节点的前一 个节点,这次双向链表 temp就直接是待删除的节点。 单向链表的链接如下: 数据结构+算法连载四 单向链表(无序+有序) 数据结构+算法连载五 单向链表的几道练习题 ...

cyberHerman的博客 1441

【Linux】实际项目应该如何完成?--安防监控系统项目的总结

到目前为止我也做个5、6个嵌入式项目,但以往都是从零开始自己做,也就是毫无计划,想到那里做那里,有想法就会去实现,就这样导致我碰到了很多坑,也消耗了我许多时间,当然,不是说这样不好,因为在其中我也得到了一个很好的锻炼与练习,但是这不适用于在工作中去这样做。...

修成真的博客 6725

数据结构之双向链表

数据结构之双向链表

容铎的博客 1373

Xilinx Vitis 2020.1头文件路径配置避坑指南:解决#include找不到文件的常见问题

本文针对Xilinx Vitis 2020.1开发环境中常见的#include头文件找不到问题,提供了系统的避坑指南。文章深入解析了Vitis的头文件搜索机制,对比了通过工程属性GUI、修改编译命令及使用环境变量三种配置方法的优劣与隐藏陷阱,并给出了高级场景的排查流程与工程结构最佳实践,帮助开发者高效解决路径配置难题。

weixin_28831399的博客 569

单片机课程设计——交通灯

单片机课程设计——交通灯一、课程设计主要内容1.1 题目1.2摘要1.3关键词二、设计要求三、设计方案四、参考电路设计4.1.1数码管的设计4.1.2对应程序4.2.1独立按键的设计4.2.2对应程序4.2.3 使用逻辑4.3.1LED模块的设置4.3.2 LED实物图4.3.3 LED显示程序五、调试要点5.1 单片机最小系统5.2 数码管模块5.3 LED模块5.4 独立按键六、总结七、成品图完整程序 一、课程设计主要内容 1.1 题目 交通灯设计 1.2摘要 近年来,随着我国国民经济的快速发展,我国机

PKPROTEUS的博客 3万+

自定义实现数据结构中的双向链表(JAVA实现)

** 自定义实现数据结构中的双向链表 ** 双向链表是数据结构线性表中的一种,较单向表来说,使用起来会更加方便,特别是在插入和删除时能更好寻找结点,所以我尝试着自己来实现一下双向链表,供大家参考和提建议,找bug。 首先要弄清楚双向链表的结构:结点 Node,每个结点都由三个部分组成,直接前驱指示previous,结点中的对象object,直接后继指示next,结点如图 结点实现如下: public class Node { /*private*/ Node privoius; /*pr

Andyxjx的博客 1832

华为OD机试真题2026双机位C卷 C语言 实现【明日之星选举】

给定一组选票votes。votes[i]代表第 i 张选票的内容,包含一个字符串"zhangsan,hanmei",表示推荐zhangsan为明日之星,反对 hanmei 称为明日之星。赞成或反对使用逗号(,)分割。 给定一个数组n,表示最后将筛选出赞成票最多的n个人,如果赞成票相同,则反对票越少,排序越靠前;如果赞成票和反对票都相同,则按照姓名字典序升序排序。

MISAYAONE的博客 182

C语言-双向链表的详解和实现

/ 双向链表节点结构int data;// 节点数据域// 指向前一个节点的指针// 指向后一个节点的指针} Node;// 双向链表结构体定义Node* head;// 头结点指针,指向链表的头部int size;// 链表中节点的数量双向链表通过每个节点存储前驱和后继节点的指针,支持从任意位置直接访问前后节点,使得插入、删除等操作在某些场景下比单链表更加高效。

qq_42037383的博客 676

windows下玩转vllm:在wsl下安装vllm

当前,部署通义千问2.5-vl已经是一件箭在弦上,不得不发的事儿了。网上搜了一下,发现还是用vllm用的比较多。于是乎,这就开始尝试部署vllm。但是我们之前说了,vllm是不支持直接在windows上部署的,我们还得搞wsl或者docker。咱今天先尝试使用wsl进行安装哈。

xiezhipu的博客 4136

Avalonia+ReactiveUI跨平台路由:从零到舞者,你的UI也能跨界起舞?

至此,你已掌握了Avalonia+ReactiveUI的跨平台路由精髓!你的应用现在能够优雅地在各个界面间穿梭,就像是在不同星球间跳跃的宇宙飞船。无论是初探跨平台开发的新手,还是经验丰富的老船长,这段旅程都能让你的UI编排技能更上一层楼。现在,是时候让世界见证你的跨平台魔术了!💫记住,每一次实践都是向着完美编舞迈进的一步,勇敢地在你的项目中尝试吧!如果在航行中遇到风暴,别忘了回来看看这篇指南,或者在评论区抛出你的救生圈,我们一起解决!🌊。

java专栏 1534

实现一个自己的双向链表

实现一个自己的双向链表

qq_45826058的博客 277

《手把手教你YOLOv9实战》,改进专栏目录

为了提供友好的操作效果,本专栏将会手把手搭建可视化界面,我将用PyQt5 搭建一个可视化界面,可视化界面能够实现基本的图像加载与检测功能,如支持视频、摄像头,还支持更换不同的 YOLOv9 模型,并适应不同领域(如口罩检测系统、人脸检测系统、工业缺陷检测系统等),界面灵活、功能强大。通过YOLOv9加以改进设计,形成新的算法框架,一起水科研和论文,专栏会一直持续更新中,本专栏适合目标检测、分割、分类。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2151

java数据结构双链表的自定义实现

package com.wck.test83; /** * @author kun * @date 2021年8月3日 */ public class DoublyLinkedList { class Node{ Object item; Node next; Node prior; } Node head=new Node(); int size=0; int flag=1; Node temp; public boolean i

进阶的菜鸟 274

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

线性表-双链表

双链表节点的实现 DLink.h template class DLink { private: static DLink* freelist; public: Elem element; DLink *next; DLink *prev; DLink(const Elem& e, DLink* prevp = NULL, DLink* nextp = NULL) {

bluegreen315的专栏 536

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

日常学习随笔-自定义了一个双链表(注释蛮详细的)

一、双链表结构   最近总会抽出一些零碎的时间片段,尝试按照自己的想法自定一了一个双链表结构的集合。我发现,数组、单链表或者双链表,乃至其他结构,本质上就是一种思想,只要遵循结构的核心思想,实现方法会有很多种。数组和单链表就不多说了,前几篇也尝试自定义了,就双链表来说,就可以定义如下几种结构: (1)头结点+...数据结点.....+尾结点 (2)头结点+...数据结点..... (3)头...

weixin_34344677的博客 152

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

自己实现链表数据结构 LinkedList

package com.crg.linkedlist;import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; /** * 实现一个自定义的双链表数据结构的 LinkedList * @author crg * *

Jack_SivenChen的博客 677

java双链表数据结构

package list; /** * 双链表数据结构及其增、删、改、查 * * @author liyulin * @param * @version 1.0 2013-9-26 上午12:19:11 */ public class MyLinkedList { /** 链表的大小 */ private int size = 0; /** 链表的首元素 */ priv

6万+

双链表(王道数据结构)

char10typedef struct DNode //定双链表结点类型//每个结点存放一个数据元素//指针指向下一节点//指针指向上一节点。

2302_80796399的博客 686

RT-Thread系列--双链表分析

RT-Thread双链表结构讲解

coderma的博客 4154

python链表如何储存_python怎么实现链表

一、概念梳理链表是计算机科学里面应用应用最广泛的数据结构之一。它是最简单的数据结构之一,同时也是比较高阶的数据结构(例如棧、环形缓冲和队列)简单的说,一个列表就是单数据通过索引集合在一起。在C里面这叫做指针。比方说,一个数据元素可以由地址元素,地理元素、路由信息活着交易细节等等组成。但是链表里面的元素类型都是一样的,是一种特殊的列表。一个单独的列表元素叫做一个节点。这些节点不像数组一样都按顺序存储...

weixin_39989939的博客 359

循环双链表Java

参考 算法导论 java数据结构与算法之双链表设计与实现 package com.example; import com.sun.org.apache.bcel.internal.classfile.PMGClass; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; import java.util.ArrayList...

谢耀眼 273

Java实现二叉树、 双链表

双链表: public class MyDoubleLink implements Iterable{ private class Node { Node next; // 下一个节点 Node prev; // 前一个节点 Object data; // 数据 } private Node head; // 头节点 private Node rear; // 尾节点

多多洛写技术博客的地方 488

Carl代码随想录算法训练营-Day 10-栈与队列理论基础、232.用栈实现队列、225. 用队列实现栈

从原理上分析了栈与队列的理论基础知识,并用自定义双链表结构完成了实现。完成了leetcode上232.用栈实现队列、225. 用队列实现栈,一共两道相关题目,进行了具体的思路分析以及Java代码实现。

BuleFACE_Zhang的博客 1133

java中链表的数据结构的理解

Java 中链表通常由一个节点类 (ListNode) 和可能的链表操作类构成。节点类 (ListNode)这是链表的基本组成部分,每个节点包含数据域和指向下一个节点的引用。int val;// 数据域// 指向下一个节点的引用// 构造函数自定义链表:适用于需要实现特定链表功能的场景。单链表:每个节点只有next引用。双链表:每个节点有next和prev引用,操作更加灵活。Java 标准库LinkedList:提供开箱即用的链表操作,适合一般用途。

牛马日常踩坑记录 563

自定义链表小结

自定义一个链表可以先创建一个结点类,结点类中除了有要储存的内容外 还必需有其它结点的引用,因为链表的储存方式是不连续的,只有结点不断 的引用其它结点才能把所有结点连起来,使整个链表完整,链表有单链表和 双链表之分,单链表是每个结点只引用后一个结点,而双链表是每一个结点 都引用了与它相邻的两个结点,我们可以根据具体情况来设置结点引用的个 数。创建好了结点类后,可以再创建一...

长草 206
上一篇: 蓝桥杯之还款计算
下一篇: 归并排序
LuFei_java
博客等级 码龄10年 1粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值