一.双向链式存储: 

    ①简述:要是节点中包含两个指针部分,一个指向前驱元,一个指向后继元,Java中LinkedList集合类的实现就是双向链表

    

     (以下图片为网络收集,侵删)

    ②特点:数据是非连续的,链表的运输必须从头指针开始;

    ③单链表相关操作:

      A.插入操作

        

      B.删除操作

        

    ④代码实现: 

    无头结点的双向链表

public class LinkedList<E> extends AbstractList<E> {
private Node<E> first;
private Node<E> last; private static class Node<E> {
E element;
Node<E> prev;
Node<E> next;
public Node(Node<E> prev, E element, Node<E> next) {
this.prev = prev;
this.element = element;
this.next = next;
} @Override
public String toString() {
StringBuilder sb = new StringBuilder(); if (prev != null) {
sb.append(prev.element);
} else {
sb.append("null");
} sb.append("_").append(element).append("_"); if (next != null) {
sb.append(next.element);
} else {
sb.append("null");
} return sb.toString();
}
} @Override
public void clear() {
size = 0;
first = null;
last = null;
} @Override
public E get(int index) {
return node(index).element;
} @Override
public E set(int index, E element) {
Node<E> node = node(index);
E old = node.element;
node.element = element;
return old;
} @Override
public void add(int index, E element) {
rangeCheckForAdd(index); // size == 0
// index == 0
if (index == size) { // 往最后面添加元素
Node<E> oldLast = last;
last = new Node<>(oldLast, element, null);
if (oldLast == null) { // 这是链表添加的第一个元素
first = last;
} else {
oldLast.next = last;
}
} else {
Node<E> next = node(index);
Node<E> prev = next.prev;
Node<E> node = new Node<>(prev, element, next);
next.prev = node; if (prev == null) { // index == 0
first = node;
} else {
prev.next = node;
}
} size++;
} @Override
public E remove(int index) {
rangeCheck(index); Node<E> node = node(index);
Node<E> prev = node.prev;
Node<E> next = node.next; if (prev == null) { // index == 0
first = next;
} else {
prev.next = next;
} if (next == null) { // index == size - 1
last = prev;
} else {
next.prev = prev;
} size--;
return node.element;
} @Override
public int indexOf(E element) {
if (element == null) {
Node<E> node = first;
for (int i = 0; i < size; i++) {
if (node.element == null) return i; node = node.next;
}
} else {
Node<E> node = first;
for (int i = 0; i < size; i++) {
if (element.equals(node.element)) return i; node = node.next;
}
}
return ELEMENT_NOT_FOUND;
} /**
* 获取index位置对应的节点对象
* @param index
* @return
*/
private Node<E> node(int index) {
rangeCheck(index); if (index < (size >> 1)) {
Node<E> node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
} else {
Node<E> node = last;
for (int i = size - 1; i > index; i--) {
node = node.prev;
}
return node;
}
} @Override
public String toString() {
StringBuilder string = new StringBuilder();
string.append("size=").append(size).append(", [");
Node<E> node = first;
for (int i = 0; i < size; i++) {
if (i != 0) {
string.append(", ");
} string.append(node); node = node.next;
}
string.append("]");
return string.toString();
}
}

java数据结构-05双向链表的更多相关文章

  1. JAVA数据结构--LinkedList双向链表

    链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括两个部分: ...

  2. Java 数据结构之双向链表

    一.概述: 1.什么是双向链表: 链表中的每个节点即指向前面一个节点,也指向后面一个节点,就像丢手绢游戏一样,每个人都手拉手 2.从头部插入 要对链表进行判断,如果为空则设置尾节点为新添加的节点,如果 ...

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

    上一篇文章说到了单链表,也通过案例具体实现了一下,但是单链表的缺点也显而易见. 单向链表查找的方向只能是一个方向 单向链表不能自我删除,需要靠辅助节点 而双向链表则能够很轻松地实现上面的功能. 何为双 ...

  4. Java数据结构之双向链表

    管理单向链表的缺点分析: 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找. 单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除,所以前面我们单链表删除时节点,总是找 ...

  5. Java数据结构之线性表

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  6. (6)Java数据结构-- 转:JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析  http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balab ...

  7. Java数据结构和算法(一)线性结构

    Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...

  8. 一文掌握关于Java数据结构所有知识点(欢迎一起完善)

    在我们学习Java的时候,很多人会面临我不知道继续学什么或者面试会问什么的尴尬情况(我本人之前就很迷茫).所以,我决定通过这个开源平台来帮助一些有需要的人,通过下面的内容,你会掌握系统的Java学习以 ...

  9. Java数据结构和算法(四)--链表

    日常开发中,数组和集合使用的很多,而数组的无序插入和删除效率都是偏低的,这点在学习ArrayList源码的时候就知道了,因为需要把要 插入索引后面的所以元素全部后移一位. 而本文会详细讲解链表,可以解 ...

随机推荐

  1. 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳

    学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 ...

  2. 【FastDFS】小伙伴们说在CentOS 8服务器上搭建FastDFS环境总报错?

    写在前面 在[冰河技术]微信公众号的[分布式存储]专题中,我们分别搭建了单节点FastDFS环境和高可用FastDFS集群环境.但是,之前的环境都是基于CentOS 6.8服务器进行搭建的.很多小伙伴 ...

  3. java并发编程--Synchronized的理解

    synchronized实现锁的基础:Java中每一个对象都可以作为锁,具体表现为3种形式. (1)普通同步方法,锁是当前实例对象 (2)静态同步方法,锁是当前类的Class对象 (3)同步方法块,锁 ...

  4. @ComponentScan比较

    ComponetScan 定义扫描规则 value:指定要扫描的包 excludeFilters=Filter[] 指定扫描的时候按照什么规则排除哪些组件. includeFilters=Filter ...

  5. Python-组织结构-目录结构、包导入、__init__文件、模块内置变量、* 导入限制

    __pycache__ .pyc文件,中间代码,提升python运行效率 目录 分档和归类 Python项目组织结构 包 模块 类 函数.变量 # 层级依次往下都是一对多关系 Python项目目录结构 ...

  6. JS之回调函数(callback)

    1.什么是回调函数? -- 简单点说,一个函数被作为参数传递给另一个函数(在这里我们把另一个函数叫做"otherFunction"),回调函数在otherFunction中被调用. ...

  7. P4454 [CQOI2018]破解D-H协议

    链接 这题并不难只是需要把题读懂 - By ShadderLeave 一句话题意 给定两个数 \(p\)和\(g\),有\(t\)组询问,每组询问给出\(A\)和\(B\) 其中 A = \(g^a ...

  8. 【学习笔记/题解】树上启发式合并/CF600E Lomsat gelral

    题目戳我 \(\text{Solution:}\) 树上启发式合并,是对普通暴力的一种优化. 考虑本题,最暴力的做法显然是暴力统计每一次的子树,为了避免其他子树影响,每次统计完子树都需要清空其信息. ...

  9. angularCroppie

    下载 angularCroppieangularCroppie 图像Cropper使用Croppie 安装 Npm: Npm安装角croppie 使用 添加依赖项:angular.模块("m ...

  10. Git本地已有项目关联远程仓库

    情况: 本地已有项目 远程有个仓库 目的: 本地项目关联远程仓库 首先要把本地项目变成git管理的,也就是建立一个本地仓库,可以在项目目录下面使用git init命令初始化仓库,初始化成功之后会在仓库 ...