首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

双向链表序列上的Java迭代

双向链表是一种数据结构,它由一系列节点组成,每个节点包含一个数据元素和两个指针,分别指向前一个节点和后一个节点。相比于单向链表,双向链表可以在节点之间进行双向遍历。

在Java中,可以通过自定义类来实现双向链表。以下是一个简单的双向链表的Java实现示例:

代码语言:txt
复制
class Node {
    int data;
    Node prev;
    Node next;
    
    public Node(int data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

class DoublyLinkedList {
    Node head;
    
    public DoublyLinkedList() {
        this.head = null;
    }
    
    // 在链表末尾插入一个节点
    public void insert(int data) {
        Node newNode = new Node(data);
        
        if (head == null) {
            head = newNode;
        } else {
            Node current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
            newNode.prev = current;
        }
    }
    
    // 在链表中删除一个节点
    public void delete(int data) {
        if (head == null) {
            return;
        }
        
        Node current = head;
        while (current != null) {
            if (current.data == data) {
                if (current.prev != null) {
                    current.prev.next = current.next;
                } else {
                    head = current.next;
                }
                
                if (current.next != null) {
                    current.next.prev = current.prev;
                }
                
                return;
            }
            current = current.next;
        }
    }
    
    // 遍历链表并打印节点值
    public void print() {
        Node current = head;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }
}

public class Main {
    public static void main(String[] args) {
        DoublyLinkedList list = new DoublyLinkedList();
        
        list.insert(1);
        list.insert(2);
        list.insert(3);
        
        list.print();  // 输出:1 2 3
        
        list.delete(2);
        
        list.print();  // 输出:1 3
    }
}

双向链表在某些场景下具有一些优势,例如:

  1. 可以在常数时间内在任意位置插入或删除节点,而单向链表需要遍历到目标位置才能进行插入或删除操作。
  2. 可以在常数时间内进行双向遍历,而单向链表只能进行单向遍历。
  3. 可以更方便地实现某些算法,如LRU缓存淘汰算法。

双向链表在实际开发中有许多应用场景,例如:

  1. 实现LRU缓存淘汰算法:双向链表可以记录访问顺序,当缓存满时,可以快速删除最久未使用的节点。
  2. 实现浏览器的前进和后退功能:双向链表可以记录浏览历史,通过前进和后退操作来切换页面。
  3. 实现编辑器的撤销和重做功能:双向链表可以记录操作历史,通过撤销和重做操作来恢复之前的编辑状态。

腾讯云提供了多个与双向链表相关的产品和服务,例如:

  1. 云服务器(ECS):提供可扩展的计算能力,适用于部署和运行各种应用程序。
  2. 云数据库MySQL版(CDB):提供高性能、可扩展的关系型数据库服务,适用于存储和管理数据。
  3. 云原生容器服务(TKE):提供高度可扩展的容器化应用程序管理平台,适用于部署和管理容器化应用。
  4. 云存储(COS):提供安全可靠的对象存储服务,适用于存储和管理大规模的非结构化数据。

你可以通过访问腾讯云官方网站(https://cloud.tencent.com/)了解更多关于这些产品的详细信息和使用指南。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

链表双向链表实现

前言 ---- 链表数据通过指针连接,添加、插入或删除节点只需要修改指针指向 实现思路 实现一个链表需要具备以下方法 在链表尾部添加节点 获取链表所有节点数据 链表指定位置插入元素 获取链表指定位置节点数据...获取节点在链表位置 更新链表指定位置数据 移除链表指定位置节点 移除链表指定节点 判断链表是否为空 获取链表长度 链表内部需要定义head指针和链表长度 实现代码 定义head指针和length...(linkedList.size()) 双向链表 双向链表指针是双向,前指针指向上一个节点,后指针指向下一个节点 head指向第一个节点,tail指向最后一个节点 双向链表实现思路 需要具备以下方法...尾部插入元素 任意位置插入元素 获取所有节点数据 正向遍历链表获取节点数据 反向遍历链表获取节点数据 获取指定位置节点数据 获取指定数据在链表位置 更新指定位置节点数据 移除指定位置节点 移除指定数据节点...判断链表是否为空 获取链表长度 定义head和tail分别指向第一个节点和最后一个节点 代码实现 /** * 双向链表 */ function DoublyLinkedList() { //指向第一个节点

68540

单向链表双向链表区别的意义 - Java

众所周知,链表是常用数据结构,在Java中有很多基于链表容器实现类,例如HashMap、LinkedList。但是这些链表有的是单向链表,有的是双向链表,那么他俩有什么不同呢?...(以下源码均属于jdk1.8.0_101) 双向链表有前后两个节点指针,可以回溯指针,方便节点删除,移动,在做删除操作时只需要将索引节点前后两个节点连接即可,但是相比单向链表会耗费额外资源。...单向链表只有后一节点指针,在节点删除,移动时候,需要暂存前一节点,删除时候将前一节点和后一节点连接,因为比双向链表少维护一个前节点,只在删除时候暂存,所以比单向链表节省资源,但是增加了操作复杂性...单向链表 ? image.png 双向链表 ? image.png 源码分析 1....LinkedList - 双向链表 直接连接前后节点 Node private static class Node { E item; Node next; Node

1.1K20

循环双向链表

链表使用 初级版:   结构体   struct data{     struct data* next;     int data;   };   head=p1->p2->p3->p4->NULL...  需要删除节点p3时就很麻烦,我们需要从头去遍历,找到next指针为p3时将next指针指向p3next;   为此方便起见,我们可以使用双向链表进行实现。...内核中是这样处理,   创建一个双向循环链表   =>headp1p2p3p4=   向链表中指定位置插入节点   原有链prenext   这也是最基本插入节点方法...}   根据插入节点方式写删除节点就容易多了   _del(struct data * pre,struct data * next){     pre->next = next;     next...}   没有做释放代码,创建链时候需要用malloc去创建,内核中双向链表正是这么实现,   特别容易书写,不太会产生副作用。二级指向是在太难理解了

27610

Java——数据结构之双向链表

Java——数据结构之双向链表   接上篇Java——数据结构之单链表   在之前学习中,我们主要了解了很多 Java 基本语法,但是 在之后 Java学习中,了解 基础 数据结构知识 非常重要...,数据结构思想 可以帮助我们更加清晰 明白了解 Java 解题思路等等。   ...今天我们就来开始学习 实现一个 Java 基础 不带头双向非循环链表。...作为双向链表,可以从头节点遍历到尾节点,同时也可以从尾节点遍历到头节点,所以我们要定义两个节点—— head头节点,last尾节点 public ListNode head; public...(2)头插法   以上述结构为例,这个单链表没有专门傀儡节点来充当头节点,首个节点就定义为头节点,所以头插法,就是我们定义一个节点,插在这个链表最前面,作为新 head。

69911

数据结构Java实现:循环链表双向链表

上篇教程给大家分享了单链表概念,以及如何用 Java 实现一个单链表结构:数据结构Java实现:单链表。...接下来用 Java 实现一个循环链表结构,只需要在原有单链表基础上稍作修改即可,如下所示。...而双向链表顾名思义是双向连接,既可以从当前节点访问到后继节点,也可以访问到前驱节点,所以在双向链表中有两个指针,一个叫做后继指针,指向下一个节点,另一个叫做前驱指针,指向它上一个节点,双向链表结构如下图所示...双向链表相比于单链表会占用更多内存空间,因为多了一个指针来存储前驱节点内存地址。虽然如此,但是在某些操作上,相比于单链表双向链表可以极大地提升效率。...如果是双向链表结构,每一个节点都会记录其前驱节点,可直接获取,所以此时时间复杂度为 O(1)。 ? 搞清楚了双向链表概念,接下来我们用 Java 来实现双向链表结构。

3.4K20

双向链表优雅实现

文中涉及代码可访问 GitHub:https://github.com/UniqueDong/algorithms.git 上次我们说了「单向链表代码实现,今天带大家一起玩下双向链表双向链表节点比单项多了一个指针引用...双向链表就像渣男,跟「前女友」和「现女友」,还有一个「备胎』都保持联系。前女友就像是前驱节点,现女友就是 「当前 data」,而「next」指针就像是他套住备胎。...使用这样数据结构就能实现「进可攻退可守」灵活状态。 接下来让我们一起实现『渣男双向链表』。...prev; this.item = item; this.next = next; } } 代码实现 定义好渣男节点后,就开始实现我们双向链表...,要考虑当前链表只有一个节点情况,最后还要把被删除节点 next 指针 ,item 设置 null,便于垃圾回收,防止内存泄漏。

79930

图解Java数据结构之双向链表

上一篇文章说到了单链表,也通过案例具体实现了一下,但是单链表缺点也显而易见。 单向链表查找方向只能是一个方向 单向链表不能自我删除,需要靠辅助节点 而双向链表则能够很轻松地实现上面的功能。...何为双向链表 双向链表也叫双链表,是链表一种,它每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表任意一个结点开始,都可以很方便地访问它前驱结点和后继结点。...增删改查思路分析 对于单链表,我们已经有所了解,并且掌握了增删改查,而双向链表与单链表唯一不同之处就在于多了一个指向前一个节点指针。...虽然只有这点不同,但是双向链表在增删改查实现上还是与单链表有很多不一样之处。...,关于双向链表操作将非常简单,两者只是有一些细微差别,并无大变化。

1.3K10

循环链表实现_建立双向循环链表

循环链表   循环链表是一个收尾相接链表,将单链表最后一个指针域改由NULL改为指向表头结点这就是单链式循环链表,并称为循环单链表   带头结点循环单链表各种操作算法实现与带头结点单链表算法实现类似...单链表判别条件为p!=NULL或p->next!=NULL,而单循环链表判别条件是p!=L或p->next!=L   在循环单链表中附设尾指针有时候比附设头指针更简单。...如:在用头指针循环单链表中找a1时间复杂度是O(1),找an需要从头找到尾,时间复杂度是O(n),如果用为指针rear,找开始结点和终端结点存储位置分别是rear->next->next和rear...    方法一:先找到两个链表LA,LB表尾,分别用p,q指向它,然后将第一个链表表尾与第二个链表第一个结点连起来,修改第二个表尾q,使它链域指向第一个表头 //头指针合并循环链表 #include...;//返回新链表尾指针 }   循环链表求长度 #include #define len sizeof(Node) #include typedef struct

73220

双向链表增删改查

双向链表,我们曾经拿了一幅非常形象图片来形容他,就像几个人手拉手围成一个圈一样。在我们代码中呈现就是每个节点都有一个指向下一个节点指针,同时也有一个指向上一个节点指针。...(如图) 双向链表图形表示: 【实现代码】 因为插入和删除节点步骤跟单向循环链表差不多,只是多了一个前驱指针,我们这里值给出代码,具体插入和删除操作示例图就不一一列举了。...#ifndef _DLINK_LIST_H #define _DLINK_LIST_H //自定义双向链表数据类型 typedef void DLinkList; //自定义双向链表节点数据类型 typedef...打印链表长度 printf(“打印链表长度, Length = %d\n”, DLinkList_Length(dlist)); //销毁双向链表 DLinkList_Destroy(dlist);...} void main() { dLinkListTest(); system(“pause”); } 双向链表增加了前驱指针,在功能上完全是可以替代单向链表,并且通过前驱指针我们可以更高效遍历所有元素

12010

单循环链表-带头双向循环链表实现

今天我们就来学习一下结构最复杂带头双向循环链表!!!...;   虽然名字听上去比较复杂单循环链表,但是实现起来比单链表(全名:不带头、不循环、单向链表)更加简单,也不需要过多考虑特殊情况;   两种链表比较:(上面是单链表,下面是带头双向循环链表)   结构分析...  首先链表头节点是不存储有效数据(该节点被称为哨兵位),其次我们只需要知道改头节点指针就能找到整个链表单循环链表,并且便于对整个链表进行维护;   当然既然是双向嘛,那节点一定有个指针域指向前一个节点...  该链表尾插,比单链表尾插简单太多了,不用遍历找尾:    // 双向链表尾插 void ListPushBack(ListNode* pHead, LTDataType...// 双向链表在pos前面进行插入 void ListInsert(ListNode* pos, LTDataType x); // 双向链表删除pos位置节点 void

59130

双向链表类模板实现

全部代码加详细注释 List.hpp写法1----将迭代器类,节点类和链表类分开写,变量不统一,书写较麻烦 /***************Node结点定义************/ template...} //******************************************************************* }; /***************链表类模板定义...} //返回尾元素引用---我们在迭代函数里面重载了*,因此解引用迭代器返回是当前迭代current指针指向data数据域 //但注意返回应该是end迭代器前一个,即最后一个位置有效元素...模板变量参数统一化,便于书写 #pragma once #include #include using namespace std; /***************链表类模板定义...//返回尾元素引用---我们在迭代函数里面重载了*,因此解引用迭代器返回是当前迭代current指针指向data数据域 //但注意返回应该是end迭代器前一个,即最后一个位置有效元素

95610

双向链表三种实现

这篇文章,其实很像是“茴字四种写法”。这让人不由想起来孔乙己。在我印象中,大多数人对孔乙己是持嘲讽态度。 但是从技术上讲,我觉得”茴字四种写法”在满足需求前提下,有助于我们简化实现。...在我历史经验中,我一共写过三种双向链表。 在最开始实现时,就是按算法导论最朴素实现。...最近在Review几年前代码时,发现之前使用算法1写双向链表有bug. 这再次使我想对双向链表算法2进行改进,我仔细思考了一下双向链表特性。...双向链表主要有两个功能: 提供反向遍历 以O(1)时间复杂度删除某个节点 但是到目前为止, 我从来没有使用过双向链表特性1. 我使用双向链表惟一原因就是要快速删除某一个节点。...最终我发现,在整个逻辑中,prev指针惟一用处就是用来访问或修改前置节点next变量。 而headprev变量同样是多余

50320

双向链表增,删,改,查

但是双向链表就不存在这个问题,在对双向链表做追加操作时只需要对头结点节点进行一次遍历就到达了链表尾部。这样就大大减少了时间上开销。...以下是双向链表结构示意图: 可以看出,每个节点都有两个指针,一个指向前面,一个指向后面。指向前面的叫先节点,指向后面的叫后继结点。 我们通过这两个指针来访问所有节点,并通过他们来对链表进行操作。...Reverse_PrintList(Node *head) //倒打印所有节点   {   Node *temp = head;   while (head->prior!...\r\n");   system("pause");   return 0;   } 还有些资料可以给学习伙伴参考 循环链表及线性表应用 http://www.makeru.com.cn/course...s=45051 C语言(系列“点标题下开始学习就可以看了”) http://www.makeru.com.cn/course/details/2233?

66030

Android中双向链表「建议收藏」

1.看源代码必须搞懂Android数据结构。在init源代码中双向链表listnode使用非常多,它仅仅有prev和next两个指针,没有不论什么数据成员。...这里须要考虑一个问题是,链表操作都是通过listnode进行,但是那只是是个连接件。...当我们顺着链表取得当中一项listnode结构时,又如何找到其宿主结构呢?在listnode结构中并没有指向其宿主结构指针啊。毕竟。我们我真正关心是宿主结构。而不是连接件。...node_to_item(node,container,member) \ (container*)(((char*)(node))-offsetof(container,member)) //向list双向链表尾部加入...node节点,list始终指向双向链表头部(这个头部仅仅含有prev/next) void list_add_tail(listnode *list,listnode *node) {

66710

DS:带头双向循环链表实现

一、链表分类 链表结构⾮常多样,组合起来就有8种(2 x 2 x 2)链表结构: 1.1 单向或者双向 双向链表,即上一个结点保存着下一个结点地址,且下一个结点保存着上一个结点地址...虽然有这么多链表结构,但是我们实际中最常用还是两种结构: 单链表(不带头单向不循环链表)和 双向链表(带头双向循环链表) 1. 无头单向非循环链表:结构简单,⼀般不会单独⽤来存数据。...实际中使⽤链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使⽤代码实现以后会发现结构会带 来很多优势,实现反⽽简单了,后⾯我们代码实现了就知道了。...二、带头双向循环链表结构 带头链表头节点,实际为“哨兵位”,哨兵位节点不存储任何有效元素,只是站在这⾥“放哨” “哨兵位”存在意义:遍历循环链表避免死循环。...三、双向链表结点结构体创建 与单链表结点结构体不同是,双向链表结点结构体多了一个前驱结点!!

9910

【数据结构】—带头双向循环链表实现(完美链表

目录 前言 链表实现 新节点创建 链表初始化 尾插与尾删 头插与头删 查找数据 在任意位置插入与删除 链表销毁 总结 前言 链表结构一共有八种形式,在前面的文章里已经讲完了不带头单向非循环链表实现...,但是我们发现该链表实现尾插与尾删时比较麻烦,要先从头节点进行遍历,找到尾节点,时间复杂度为O(N),而本次所讲带头双向循环单链表,则可以直接找到尾节点。...// 双向链表在pos前面进行插入 void ListInsert(ListNode* pos, LTDataType x) { assert(pos); //pos前面的节点 ListNode...ListNode* curnext = cur->_next; free(cur);//释放 cur = curnext; } //释放pHead free(pHead); } 测试 //双向链表查找...//查找 ListNode* pos = ListFind(phead, 2); //pos->_data = 50; //ListPrint(phead);// 5 4 3 50 1 // 双向链表

55320

Linux内核中双向链表经典实现

概要 本文对双向链表进行探讨,介绍内容是Linux内核中双向链表经典实现和用法。其中,也会涉及到Linux内核中非常常用两个经典宏定义offsetof和container_of。...Linux中双向链表经典实现 1.Linux中双向链表介绍 Linux双向链表定义主要涉及到两个文件: include/linux/types.h include/linux/list.h Linux...中双向链表使用思想 它是将双向链表节点嵌套在其它结构体中;在遍历链表时候,根据双链表节点指针获取"它所在结构体指针",从而再获取数据。...节点定义 1 struct list_head { 2 struct list_head *next, *prev; 3 }; 虽然名称list_head,但是它既是双向链表表头,也代表双向链表节点...3.Linux中双向链表使用示例 双向链表代码(list.h): 1 #ifndef _LIST_HEAD_H 2 #define _LIST_HEAD_H 3 // 双向链表节点 4 struct

2.6K30
领券