本文根据《大话数据结构》一书,实现了Java版的双向链表

在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表

双向链表的结构如图所示:

  • 查找元素可以根据元素的位置,分别沿正向和反向查找。

双向链表实现程序:

package DuLinkList;

public class DuLinkList<E> {
private Node<E> head;
private int count; /**
* 结点
*/
class Node<E> {
E data;
Node<E> prior;
Node<E> next; public Node(E data, Node<E> prior, Node<E> next) {
this.data = data;
this.prior = prior;
this.next = next;
}
} /**
* 线性表的初始化
*/
public DuLinkList() {
head = new Node<E>(null, null, null);
head.prior = head.next = head;
count = 0;
} /**
* 获取第i个元素
*/
public Node<E> getElement(int i) {
if (count == 0)
throw new RuntimeException("空表,无法查找!");
if (i < 1 || i > count)
throw new RuntimeException("查找位置错误!");
Node<E> node = head.next;
for (int j = 1; j < i; j++) {
node = node.next;
}
return node;
} /**
* 在第i个位置插入元素
*/
public void listInsert(int i, E data) {
if (i < 1 || i > count + 1)
throw new RuntimeException("插入位置错误!");
Node<E> node = new Node<E>(data, null, null);
if (i == 1) {
node.next = head.next;
node.prior = head;
head.next.prior = node;
head.next = node;
} else {
Node<E> pNode = getElement(i - 1);
node.next = pNode.next;
node.prior = pNode;
pNode.next.prior = node;
pNode.next = node;
}
count++;
} /**
* 删除第i个元素
*/
public E listDelete(int i) {
if (i < 1 || i > count)
throw new RuntimeException("删除位置错误!");
Node<E> node = getElement(i);
E e = node.data;
if (i == 1) {
head.next = node.next;
node.next.prior = node.prior;
node = null;
} else {
node.next.prior = node.prior;
node.prior.next = node.next;
node = null;
}
count--;
return e;
} public int listLength() {
return count;
} }

  

测试程序:

package DuLinkList;

public class DuLinkListTest {

	public static void main(String[] args) {
DuLinkList<Student> students = new DuLinkList<Student>();
System.out.println("——————————插入1到5,并读取内容——————————");
Student[] stus = { new Student("小A", 11), new Student("小B", 12), new Student("小C", 13), new Student("小D", 14),
new Student("小E", 151) };
for (int i = 1; i <= 5; i++)
students.listInsert(i, stus[i - 1]);
System.out.println("表长:" + students.listLength());
Student stu;
for (int i = 1; i <= 5; i++) {
stu = students.getElement(i).data;
System.out.println("第" + i + "个位置为:" + stu.name);
}
System.out.println("——————————删除小A、小E——————————");
stu = students.listDelete(1);
System.out.println("已删除:" + stu.name);
stu = students.listDelete(4);
System.out.println("已删除:" + stu.name);
System.out.println("当前表长:" + students.listLength());
for (int i = 1; i <= students.listLength(); i++) {
stu = students.getElement(i).data;
System.out.println("第" + i + "个位置为:" + stu.name);
}
}
} class Student {
public Student(String name, int age) {
this.name = name;
this.age = age;
} String name;
int age;
}

  

——————————插入1到5,并读取内容——————————
表长:5
第1个位置为:小A
第2个位置为:小B
第3个位置为:小C
第4个位置为:小D
第5个位置为:小E
——————————删除小A、小E——————————
已删除:小A
已删除:小E
当前表长:3
第1个位置为:小B
第2个位置为:小C
第3个位置为:小D

DuLinkListTest

——————————————————————————

在阅读过他人的博客后,发现自己的查找方法没有利用好双链表的特性,重写查找方法如下:

	/**
* 获取第i个元素
*/
public Node<E> getElement(int i) {
if (count == 0)
throw new RuntimeException("空表,无法查找!");
if (i < 1 || i > count)
throw new RuntimeException("查找位置错误!");
if (i <= count / 2) { // 正向查找
Node<E> node = head.next;
for (int j = 1; j < i; j++) {
node = node.next;
}
return node;
} else { // 反向查找
Node<E> node = head.prior;
int k = count - i;
for (int j = 0; j < k; j++) {
node = node.prior;
}
return node;
}
}

  

本文中只编写了查找和删除部分的程序,完整的双向链表程序可参阅这篇博客:数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现

【Java】 大话数据结构(5) 线性表之双向链表的更多相关文章

  1. 【Java】 大话数据结构(1) 线性表之顺序存储结构

     本文根据<大话数据结构>一书,实现了Java版的顺序存储结构. 顺序存储结构指的是用一段地址连续的存储单元一次存储线性表的数据元素,一般用一维数组来实现. 书中的线性表抽象数据类型定义如 ...

  2. 【Java】 大话数据结构(2) 线性表之单链表

    本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...

  3. 【Java】 大话数据结构(3) 线性表之静态链表

    本文根据<大话数据结构>一书,实现了Java版的静态链表. 用数组描述的链表,称为静态链表. 数组元素由两个数据域data和cur组成:data存放数据元素:cur相当于单链表中的next ...

  4. 【Java】 大话数据结构(4) 线性表之循环链表

    本文稍微介绍了一下循环链表. 将单链表终端结点的指针域由空指针改为指向头结点,形成一个环,这种头尾相接的单链表称为循环列表. 循环列表的结构如下图所示: 循环链表的优点:可以从任意一个结点出发,遍历所 ...

  5. [数据结构 - 第3章] 线性表之双向链表(C语言实现)

    一.什么是双向链表? 双向链表(double linked list)是在单链表的每个结点中,再设置一个指向其前驱结点的指针域.所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前 ...

  6. c/c++ 线性表之双向链表

    c/c++ 线性表之双向链表 线性表之双向链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,每个节点的before都指向前一个节点,最后一个节点的下一个节点是NULL. 真实 ...

  7. 用C#学习数据结构之线性表

    什么是线性表 线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系.这种一对一的关系指的是数据元素之间的位置关 ...

  8. 数据结构之线性表(python版)

    数据结构之线性表(python版) 单链表 1.1  定义表节点 # 定义表节点 class LNode(): def __init__(self,elem,next = None): self.el ...

  9. C语言数据结构-顺序线性表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作

    1.数据结构-顺序线性表的实现-C语言 #define MAXSIZE 100 //结构体定义 typedef struct { int *elem; //基地址 int length; //结构体当 ...

随机推荐

  1. 【BZOJ1797】[AHOI2009]最小割(网络流)

    [BZOJ1797][AHOI2009]最小割(网络流) 题面 BZOJ 洛谷 题解 最小割的判定问题,这里就当做记结论吧.(源自\(lun\)的课件) 我们先跑一遍最小割,求出残量网络.然后把所有还 ...

  2. HGOI 20181027 幻象(概率DP)

    40 pts: 考场上打了40分暴力,理论的话就是概率树,把每一个状态去去到各个带权(概率)的和就是答案 最终处理的话就是dfs出01序列0代表没有幻象,1代表出现幻象然后在每一次dfs出一段序列的时 ...

  3. luogu1084 [NOIp2012]疫情控制 (二分答案+倍增+dfs序)

    先二分出一个时间,把每个军队倍增往上跳到不能再跳 然后如果它能到1号点,就记下来它跳到1号点后剩余的时间:如果不能,就让它就地扎根,记一记它覆盖了哪些叶节点(我在这里用了dfs序+差分,其实直接dfs ...

  4. SQL提高查询效率【in、not in、between、like】等条件讲述

    在使用SQL语句查询数据库记录时,如果要查询相同的内容,有着不同的多种方法. 仍然,尽管使用多种方法可以得到相同的结果,但是,如果您使用不同的方法,在执行效益上是截然不同的.因此,我们得仔细考虑,如果 ...

  5. JS中的new操作符

    在JS中定义一个构造函数,然后用new操作符构造对象obj,JS代码如下. function Base(){ this.name = "swf"; this.age =20; } ...

  6. 关闭ubuntu dash 方法

    因为ubuntu默认的sh是连接到dash的,又因为dash跟bash的不兼容所以出错了.执行时可以把sh换成bash 文件名.sh来执行.成功.dash是什么东西,查了一下,应该也是一种shell, ...

  7. 鸟哥的Linux私房菜——第十八章:磁盘配额quota

    视频链接:http://www.bilibili.com/video/av10892470/ 磁盘配额quota的意思是给用户进行使用磁盘额度的空间的划分,举个例子,你的百度网盘的使用空间,其他云盘的 ...

  8. 运行fdisk命令时,弹出 bash:fdisk:command not found

    原因:命令fdisk 不在你的命令搜索路径中 第一种解决办法,将fdisk添加到你的命令搜索路径中 首先查看你当前的命令搜索路径: [root@host sbin]# echo $PATH/usr/k ...

  9. 关于css中a标签的样式

    CSS为一些特殊效果准备了特定的工具,我们称之为“伪类”.其中有几项是我们经常用到的,下面我们就详细介绍一下经常用于定义链接样式的四个伪类,它们分别是: :link :visited :hover : ...

  10. 流媒体技术学习笔记之(三)Nginx-Rtmp-Module统计某频道在线观看流的客户数

    获得订阅者人数,可以方便地显示观看流的客户数. 查看已经安装好的模块 /usr/local/nginx/sbin/nginx -V 安装从源编译Nginx和Nginx-RTMP所需的工具 sudo a ...