线性链表的双向链表——java实现
.线性表链式存储结构:将采用一组地址的任意的存储单元存放线性表中的数据元素。
链表又可分为:
单链表:每个节点只保留一个引用,该引用指向当前节点的下一个节点,没有引用指向头结点,尾节点的next引用为null。
循环链表:一种首尾相连的链表。
双向链表:每个节点有两个引用,一个指向当前节点的上一个节点,另外一个指向当前节点的下一个节点。
下面给出线性表双向链表的实现:java中LinkedList是线性表的链式实现,是一个双向链表。
import java.util.NoSuchElementException;
//线性表双向链表存储结构
public class DuLinkList<T> {
//定义一个内部类Node,Node实例代表链表的节点
private class Node{
//保存节点的数据
private T data;
//指向上一个节点的引用
private Node prev;
//指向下一个节点的引用
private Node next;
//无参数的构造器
public Node(){
}
//初始化全部属性的构造器
public Node(T data, Node prev, Node next){
this.data = data;
this.prev = prev;
this.next = next;
}
}
//保存该链表的头结点
private Node header;
//保存该链表的尾节点
private Node tail;
//保存该链表中已包含的节点数
private int size;
//创建空链表
public DuLinkList(){
//空链表,header与tail都是null
header = null;
tail = null;
}
//以指定数据元素来创建链表,该链表只有一个元素
public DuLinkList(T element){
header = new Node(element, null, null);
tail = header;
size++;
}
//判断链式线性表是否为空链表
public boolean empty(){
return size == 0;
}
//清空线性表
public void clear(){
for(Node current = header; current != null;){
Node next = header.next;
current.data = null;
current.prev = null;
current.next = null;
current = next;
}
header = null;
tail = null;
size = 0;
}
//获取链式线性表中索引为index处的元素
public T get(int index){
return getNodeByIndex(index).data;
}
//根据索引index获取指定位置的节点
private Node getNodeByIndex(int index){
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("线性表索引越界");
}
if(index < (size >> 1)){
//从header节点开始遍历
Node current = header;
for(int i=0; i < index; i++){
current = current.next;
}
return current;
}else{
Node current = tail;
for(int i = size - 1; i > index; i--){
current = current.prev;
}
return current;
}
}
//查找链式线性表中指定元素的索引
public int locate(T element){
Node current = header;
for(int i=0;i<size && current != null;i++, current = current.next){
if(current.data.equals(element)){
return i;
}
}
return -1;
}
//返回链表的长度
public int length(){
return size;
}
//向线性链表的表头插入一个元素
public void addFirst(T element){
linkFirst(element);
}
//在线性链表表头插入一个元素
public void linkFirst(T element){
Node f = header;
Node newNode = new Node(element,null,f);
header = newNode;
if(f == null){
tail = newNode;
}else{
f.prev = newNode;
}
size++;
}
//向线性链表的表尾插入一个元素
public void addTail(T element){
linkTail(element);
}
//在线性链表的表尾插入一个元素
public void linkTail(T element){
Node t = tail;
Node newNode = new Node(element, t, null);
tail = newNode;
if(t == null){
header = newNode;
}else{
t.next = newNode;
}
size++;
}
//在线性表中某个元素前面插入一个节点
public void linkBefore(T element, Node node){
Node pre = node.prev;
Node newNode = new Node(element, pre, node);
node.prev = newNode;
if(pre == null){
header = newNode;
}else{
pre.next = newNode;
}
size++;
}
//向线性链表中的指定位置插入一个元素
public void insert(T element, int index){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("线性表索引越界");
}
if(index == size){
addTail(element);
}else{
linkBefore(element,getNodeByIndex(index));
}
}
//移走线性链表的头结点
public void removeFirst(){
Node first = header;
if(first == null)
throw new NoSuchElementException("此节点不存在");
unlinkFirst(first);
}
//删除头结点
public void unlinkFirst(Node node){
Node next = node.next;
node.data = null;
node.next = null;
header = next;
if(next == null){
tail = null;
}else{
next.prev = null;
}
size--;
}
//移走线性链表的尾节点
public void removeTail(){
Node last = tail;
if(last == null)
throw new NoSuchElementException("此节点不存在");
unlinkLast(last);
}
//删除尾节点
public void unlinkLast(Node node){
Node pre = node.prev;
node.data = null;
node.prev = null;
tail = pre;
if(pre == null){
header = null;
}else{
pre.next = null;
}
size--;
}
//移走线性表中的任意一个节点
public void remove(int index){
if(index < 0 || index >size - 1){
throw new IndexOutOfBoundsException("线性表越界");
}
unlink(getNodeByIndex(index));
}
//删除线性表中任意一个元素
public void unlink(Node node){
Node pre = node.prev;
Node next = node.next;
node.data = null;
if(pre == null){
header = next;
}else{
pre.next = next;
node.prev = null;
}
if(next == null){
tail = pre;
}else{
next.prev = pre;
node.next = null;
}
size--;
}
}
线性链表的双向链表——java实现的更多相关文章
- 【Java】 大话数据结构(5) 线性表之双向链表
本文根据<大话数据结构>一书,实现了Java版的双向链表. 在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表. 双向链表的结构如图所示: 查找元素可以根据元 ...
- javascript实现数据结构:线性表--线性链表(链式存储结构)
上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...
- 【二叉树->链表】二叉树结构转双向线性链表结构(先序遍历)
二叉树存储结构属于非线性链表结构,转化成线性链表结构,能简化操作和理解.然而由非线性转线性需要对整个树遍历一次,不同的遍历方式转化结果页不一样.下面以先序为例. 方法一: 递归法.递归遍历二叉树,因为 ...
- c/c++ 线性表之双向链表
c/c++ 线性表之双向链表 线性表之双向链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,每个节点的before都指向前一个节点,最后一个节点的下一个节点是NULL. 真实 ...
- [C++]线性链表之顺序表<二>
/* @content 线性链表之顺序表 @date 2017-3-21 1:06 @author Johnny Zen */ /* 线性表 顺序表 链式表[带头指针/不 ...
- 【 C# 】(一) ------------- 泛型带头节点的单链表,双向链表实现
在编程领域,数据结构与算法向来都是提升编程能力的重点.而一般常见的数据结构是链表,栈,队列,树等.事实上C#也已经封装好了这些数据结构,在头文件 System.Collections.Generic ...
- 线性表结构的Java实现
一.线性表的抽象数据类型表述 线性表的结构简单,长度允许动态增长或搜索:可以对线性表中的任何数据元素进行访问和查找:允许进行数据的插入和删除操作:求线性表中的指定数据的前驱和后继:合并线性表以及拆分线 ...
- [数据结构 - 第3章] 线性表之双向链表(C语言实现)
一.什么是双向链表? 双向链表(double linked list)是在单链表的每个结点中,再设置一个指向其前驱结点的指针域.所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前 ...
- 数据结构算法C语言实现(五)---2.3重新定义线性链表及其基本操作
一.简述 ...由于链表在空间的合理利用上和插入.删除时不需要移动等的优点,因此在很多场合下,它是线性表的首选存储结构.然而,它也存在着实现某些基本操作,如求线性表的长度时不如顺序存储结构的缺点:另一 ...
随机推荐
- MapReduce输出格式
针对前面介绍的输入格式,MapReduce也有相应的输出格式.默认情况下只有一个 Reduce,输出只有一个文件,默认文件名为 part-r-00000,输出文件的个数与 Reduce 的个数一致. ...
- 常用Content-type汇总
Content-Type,内容类型,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式.什么编码读取这个文件.这里汇总一下常用的,所有资料来源于网络,未经测试: 文件后缀 处理方式 .* ...
- [转] 用管道获得shell 命令的输出
用管道: 通过fgets(buf, n, ptr)buf就可以得到命令“ps -ef"一样的信息, 读帮助”man popen": char *cmd = "ps -ef ...
- SQL Server中的20个系统变量
1.@@CONNECTIONS返回自上次启动 Microsoft SQL Server以来连接或试图连接的次数.示例:下面的示例显示了到当前日期和时间为止试图登录的次数.SELECT GETDATE( ...
- PHP获取文件行数
原文出处 提供两种实现方法,但是第一种效率最好 第一种: <?php $file_path = 'test.txt'; //文件路径 此处找一个1094644行的TXT文件 test.txt $ ...
- 45种Javascript技巧大全
JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发(Node.js和Wakanda)等等.JavaScript还是 ...
- iOS 集成支付宝遇到的问题(续)
调起支付宝进行支付时提示private key is null ,碰到这个问题有两种解决方案 第一种. 将私钥转成PKCS8替换一下原私钥即可 1.生成私钥pem, 执行命令openssl genr ...
- winform(C#)拖拽实现获得文件路径
设置Form的AllowDrop为true private void Form1_DragDrop(object sender, DragEventArgs e) { ...
- 安卓学习之ListView和GridView
ListView 和 GridView是安卓中显示信息的两个很基本也最常用的控件.他们的用法很相似,但是他俩也是有区别的. ListView显示的数据会将他的item放在一行显示,而且根据内容给出it ...
- Java compile时,提示 DeadCode的原因
在工程编译时,编译器发现部分代码是无用代码,则会提示:某一行代码是DeadCode.今天compile工程的时候发现某一个循环出现这个问题,如下: public void mouseOver(fina ...