JAVA数据结构--LinkedList双向链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
package DataStructures; import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException; public class MyLinkedList<AnyType> implements Iterable<AnyType> {
/*
* data当前节点的值
* prev当前节点的前缀节点
* next当前节点的后缀节点
* */
private static class Node<AnyType>{
public Node(AnyType d,Node<AnyType> p,Node<AnyType> n){
data=d;
prev=p;
next=n;
}
public AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
}
public MyLinkedList() {
doClear();
// TODO Auto-generated constructor stub
}
public void clear(){
doClear();
}
/* doClear()
* 将头结点置空
* 尾节点的前缀置为头节点
* 头结点的后缀为尾节点
* */
private void doClear(){
beginMarker=new Node<AnyType>(null, null, null);
endMarker=new Node<AnyType>(null, beginMarker, null);
beginMarker.next=endMarker;
theSize=0;
modCount++;
} public int size(){
return theSize;
}
public boolean isEmpty(){
return size()==0;
}
/*
* 在链表尾部插入新节点
* */
public boolean add(AnyType x){
add(size(), x);
return true;
}
/*
* 在链表中插入新节点
* */
public void add(int idx,AnyType x){
addBefore(getNode(idx,0,size()),x);
}
public AnyType get(int idx){
return getNode(idx).data;
}
/*
* 修改某个节点的值
* */
public AnyType set(int idx,AnyType newVal){
Node<AnyType> p=getNode(idx);//p为需要修改的节点
AnyType oldVal=p.data;
p.data=newVal;
return oldVal;
}
public AnyType remove(int idx){
return remove(getNode(idx));
} /*
* 在p节点前插入新的节点
* */
private void addBefore(Node<AnyType> p,AnyType x){
Node<AnyType> newNode=new Node<>(x, p.prev, p);//新节点的前缀为p的前缀,后缀为p
newNode.prev.next=newNode;//新节点的前缀的后缀为新节点
p.prev=newNode;//p节点的前缀为p
theSize++;
modCount++;
}
private AnyType remove(Node<AnyType> p){
p.next.prev=p.prev;
p.prev.next=p.next;
theSize--;
modCount++;
return p.data;
}
private Node<AnyType> getNode(int idx){
return getNode(idx,0,size()-1);
}
/*
* 获得某个节点
* */
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;
}
@Override
public Iterator<AnyType> iterator() {
// TODO Auto-generated method stub
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<AnyType>{
private Node<AnyType> current=beginMarker;
private int expectedModCount=modCount;
private boolean okToRemove=false;
public boolean hasNext(){
return current!=endMarker;
}
public AnyType next(){
if(modCount!=expectedModCount)
throw new ConcurrentModificationException();
if(!hasNext())
throw new NoSuchElementException();
AnyType nextItem=current.data;
current=current.next;
okToRemove=true;
return nextItem;
}
public void remove(){
if(modCount!=expectedModCount)
throw new ConcurrentModificationException();
if(!okToRemove)
throw new IllegalStateException();
MyLinkedList.this.remove(current.prev);
expectedModCount++;
okToRemove=false;
}
} private int theSize;//链表的长度
private int modCount;//链表改动的次数
private Node<AnyType> beginMarker;//头结点
private Node<AnyType> endMarker;//尾节点
}
JAVA数据结构--LinkedList双向链表的更多相关文章
- java数据结构-05双向链表
一.双向链式存储: ①简述:要是节点中包含两个指针部分,一个指向前驱元,一个指向后继元,Java中LinkedList集合类的实现就是双向链表 (以下图片为网络收集,侵删) ②特点:数据是非连续的,链 ...
- Java 数据结构之双向链表
一.概述: 1.什么是双向链表: 链表中的每个节点即指向前面一个节点,也指向后面一个节点,就像丢手绢游戏一样,每个人都手拉手 2.从头部插入 要对链表进行判断,如果为空则设置尾节点为新添加的节点,如果 ...
- 图解Java数据结构之双向链表
上一篇文章说到了单链表,也通过案例具体实现了一下,但是单链表的缺点也显而易见. 单向链表查找的方向只能是一个方向 单向链表不能自我删除,需要靠辅助节点 而双向链表则能够很轻松地实现上面的功能. 何为双 ...
- Java数据结构之双向链表
管理单向链表的缺点分析: 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找. 单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除,所以前面我们单链表删除时节点,总是找 ...
- Java 的 LinkedList 的底层数据结构
1. 数据结构--LinkedList源码摘要 public class LinkedList<E> extends AbstractSequentialList<E> imp ...
- Java数据结构之表的增删对比---ArrayList与LinkedList之一
一.Java_Collections表的实现 与c不同Java已经实现并封装了现成的表数据结构,顺序表以及链表. 1.ArrayList是基于数组的实现,因此具有的特点是:1.有索引值方便查找,对于g ...
- java通过LinkedList实现堆栈和队列数据结构
package shb.java.demo3; import java.util.LinkedList; public class TestLinkedList { /** * @author sha ...
- Java集合---LinkedList源码解析
一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...
- Java数据结构之线性表
从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...
随机推荐
- datatables01 安装、数据源、选中行事件、新增一行数据、删除一行数据
1 安装 1.1 引入必要文件 要在项目中使用datatables需要引入三个文件 >DataTables CSS >jQuery >DataTables JS <!-- Da ...
- mybatis spring 框架整合
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test user=LF password=LF <?xml versi ...
- Unix基本系统数据类型和stat结构体
Unix基本系统数据类型 历史上,某些UNIX变量已与某些C数据类型联系在一起,例如,历史上主.次设备号存放在一个1 6位的短整型中, 8位表示主设备号,另外8位表示次设备号.但是,很多较大的系统需要 ...
- c语言实践 创建两个包含8个元素的double类型数组,第二个元素的每个元素的值都是对应前一个元素的前n个元素的和
意思就是第二个元素的num[2]等于第一个元素的num[0]+num[1]+num[2] #define COUNT 8 int main(void) { double num1[COUNT]; do ...
- Jlabel实现内容自动换行
Jlabel实现内容自动换行 摘自:https://blog.csdn.net/zhhtao89/article/details/50179695 2015年12月04日 21:09:27 阅读数 ...
- ESP8266文档阅读2A-SDK-Espressif IoT SDK 使用手册v1.0.1.pdf
2A-SDK-Espressif IoT SDK 使用手册v1.0.1.pdf 1.前言 本⽂文主要介绍基于ESP8266物联⺴⽹网模块的SDK相关使⽤用⽅方法,包括开发⼯工具使⽤用以及SDK软件包架 ...
- 手打的table
突然觉得,如果我不上传源码和写篇博客,对不起花在这个破网页2个小时的时间,完全手打,浏览器调效果. 源码如下: a.html: <!DOCTYPE html PUBLIC "-//W3 ...
- 2.8.2 并发下的ArrayList,以及源码分析
package 第二章.并发下的ArrayList; import java.util.ArrayList;import java.util.List; /** * Created by zzq on ...
- C++ 中 dynamic_cast 浅析
简述:dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用.主要讲解,dynamic_cast操作符的原理.使用方式.编译器设置.返回值等相关知识. dynamic_ca ...
- 浅析C语言中assert的用法(转)
原文地址:http://www.jb51.net/article/39685.htm 以下是对C语言中assert的使用方法进行了介绍,需要的朋友可以参考下. assert宏的原型定义在<ass ...