双向链表的实现——java
/**
* Java 实现的双向链表。
* 注:java自带的集合包中有实现双向链表,路径是:java.util.LinkedList
*
* @author skywang
* @date 2013/11/07
*/
public class DoubleLink<T> { // 表头
private DNode<T> mHead;
// 节点个数
private int mCount; // 双向链表“节点”对应的结构体
private class DNode<T> {
public DNode prev;
public DNode next;
public T value; public DNode(T value, DNode prev, DNode next) {
this.value = value;
this.prev = prev;
this.next = next;
}
} // 构造函数
public DoubleLink() {
// 创建“表头”。注意:表头没有存储数据!
mHead = new DNode<T>(null, null, null);
mHead.prev = mHead.next = mHead;
// 初始化“节点个数”为0
mCount = 0;
} // 返回节点数目
public int size() {
return mCount;
} // 返回链表是否为空
public boolean isEmpty() {
return mCount==0;
} // 获取第index位置的节点
private DNode<T> getNode(int index) {
if (index<0 || index>=mCount)
throw new IndexOutOfBoundsException(); // 正向查找
if (index <= mCount/2) {
DNode<T> node = mHead.next;
for (int i=0; i<index; i++)
node = node.next; return node;
} // 反向查找
DNode<T> rnode = mHead.prev;
int rindex = mCount - index -1;
for (int j=0; j<rindex; j++)
rnode = rnode.prev; return rnode;
} // 获取第index位置的节点的值
public T get(int index) {
return getNode(index).value;
} // 获取第1个节点的值
public T getFirst() {
return getNode(0).value;
} // 获取最后一个节点的值
public T getLast() {
return getNode(mCount-1).value;
} // 将节点插入到第index位置之前
public void insert(int index, T t) {
if (index==0) {
DNode<T> node = new DNode<T>(t, mHead, mHead.next);
mHead.next.prev = node;
mHead.next = node;
mCount++;
return ;
} DNode<T> inode = getNode(index);
DNode<T> tnode = new DNode<T>(t, inode.prev, inode);
inode.prev.next = tnode;
inode.next = tnode;
mCount++;
return ;
} // 将节点插入第一个节点处。
public void insertFirst(T t) {
insert(0, t);
} // 将节点追加到链表的末尾
public void appendLast(T t) {
DNode<T> node = new DNode<T>(t, mHead.prev, mHead);
mHead.prev.next = node;
mHead.prev = node;
mCount++;
} // 删除index位置的节点
public void del(int index) {
DNode<T> inode = getNode(index);
inode.prev.next = inode.next;
inode.next.prev = inode.prev;
inode = null;
mCount--;
} // 删除第一个节点
public void deleteFirst() {
del(0);
} // 删除最后一个节点
public void deleteLast() {
del(mCount-1);
}
}
/**
* Java 实现的双向链表。
* 注:java自带的集合包中有实现双向链表,路径是:java.util.LinkedList
*
* @author skywang
* @date 2013/11/07
*/ public class DlinkTest { // 双向链表操作int数据
private static void int_test() {
int[] iarr = {10, 20, 30, 40}; System.out.println("\n----int_test----");
// 创建双向链表
DoubleLink<Integer> dlink = new DoubleLink<Integer>(); dlink.insert(0, 20); // 将 20 插入到第一个位置
dlink.appendLast(10); // 将 10 追加到链表末尾
dlink.insertFirst(30); // 将 30 插入到第一个位置 // 双向链表是否为空
System.out.printf("isEmpty()=%b\n", dlink.isEmpty());
// 双向链表的大小
System.out.printf("size()=%d\n", dlink.size()); // 打印出全部的节点
for (int i=0; i<dlink.size(); i++)
System.out.println("dlink("+i+")="+ dlink.get(i));
} private static void string_test() {
String[] sarr = {"ten", "twenty", "thirty", "forty"}; System.out.println("\n----string_test----");
// 创建双向链表
DoubleLink<String> dlink = new DoubleLink<String>(); dlink.insert(0, sarr[1]); // 将 sarr中第2个元素 插入到第一个位置
dlink.appendLast(sarr[0]); // 将 sarr中第1个元素 追加到链表末尾
dlink.insertFirst(sarr[2]); // 将 sarr中第3个元素 插入到第一个位置 // 双向链表是否为空
System.out.printf("isEmpty()=%b\n", dlink.isEmpty());
// 双向链表的大小
System.out.printf("size()=%d\n", dlink.size()); // 打印出全部的节点
for (int i=0; i<dlink.size(); i++)
System.out.println("dlink("+i+")="+ dlink.get(i));
} // 内部类
private static class Student {
private int id;
private String name; public Student(int id, String name) {
this.id = id;
this.name = name;
} @Override
public String toString() {
return "["+id+", "+name+"]";
}
} private static Student[] students = new Student[]{
new Student(10, "sky"),
new Student(20, "jody"),
new Student(30, "vic"),
new Student(40, "dan"),
}; private static void object_test() {
System.out.println("\n----object_test----");
// 创建双向链表
DoubleLink<Student> dlink = new DoubleLink<Student>(); dlink.insert(0, students[1]); // 将 students中第2个元素 插入到第一个位置
dlink.appendLast(students[0]); // 将 students中第1个元素 追加到链表末尾
dlink.insertFirst(students[2]); // 将 students中第3个元素 插入到第一个位置 // 双向链表是否为空
System.out.printf("isEmpty()=%b\n", dlink.isEmpty());
// 双向链表的大小
System.out.printf("size()=%d\n", dlink.size()); // 打印出全部的节点
for (int i=0; i<dlink.size(); i++) {
System.out.println("dlink("+i+")="+ dlink.get(i));
}
} public static void main(String[] args) {
int_test(); // 演示向双向链表操作“int数据”。
string_test(); // 演示向双向链表操作“字符串数据”。
object_test(); // 演示向双向链表操作“对象”。
}
}
本文来自http://www.cnblogs.com/skywang12345/p/3562239.html
双向链表的实现——java的更多相关文章
- 双向链表的简单Java实现-sunziren
写在前面,csdn的那篇同名博客就是我写的,我把它现在在这边重新发布,因为我实在不想用csdn了,那边的广告太多了,还有就是那个恶心人的“阅读更多”按钮,惹不起我躲得起. 在上次分享完单向链表的简单编 ...
- 线性链表的双向链表——java实现
.线性表链式存储结构:将采用一组地址的任意的存储单元存放线性表中的数据元素. 链表又可分为: 单链表:每个节点只保留一个引用,该引用指向当前节点的下一个节点,没有引用指向头结点,尾节点的next引用为 ...
- Java实现一个双向链表的倒置功能
题目要求:Java实现一个双向链表的倒置功能(1->2->3 变成 3->2->1) 提交:代码.测试用例,希望可以写成一个Java小项目,可以看到单元测试部分 该题目的代码, ...
- 线性表java实现
顺序表 public class SequenceList { /* * content,节点内容 * location,节点在表中的位置(序号) * */ private String conten ...
- Java数据结构和算法(四)--链表
日常开发中,数组和集合使用的很多,而数组的无序插入和删除效率都是偏低的,这点在学习ArrayList源码的时候就知道了,因为需要把要 插入索引后面的所以元素全部后移一位. 而本文会详细讲解链表,可以解 ...
- [Java] HOW2J(Java中级)
异常 定义:导致程序正常流程被中断的事件 异常处理常见手段 try catch:将可能抛出异常的代码放在try的块中,一旦出现异常就跳转到catch的块中处理 throws/throw:不在本模块处理 ...
- 用LinkedHashMap实现LRU算法
(在学习操作系统时,要做一份有关LRU和clock算法的实验报告,很多同学都应该是通过数组去实现LRU,可能是对堆栈的使用和链表的使用不是很熟悉吧,在网上查资料时看到了LinkedHashMap,于是 ...
- LRU算法 - LRU Cache
这个是比较经典的LRU(Least recently used,最近最少使用)算法,算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 一般应 ...
- 深入理解Redis 数据结构—双链表
在 Redis 数据类型中的列表list,对数据的添加和删除常用的命令有 lpush,rpush,lpop,rpop,其中 l 表示在左侧,r 表示在右侧,可以在左右两侧做添加和删除操作,说明这是一个 ...
随机推荐
- Vim基础教程
一.简介 世界上只有三种编辑器,EMACS.VIM和其它. 我们所处的时代是非常幸运的,有越来越多的编辑器,相对于古老的VIM和EMACS,它们被称为现代编辑器.我们来看看这两个古董有多大年纪了: * ...
- DB2事务日志
1.DB2数据库的日志原理 事务日志记录数据库中所有对象和数据的改变,在早前版本中最大可达256G,其大小为( logprimary + logsecond ) * logfilsiz,其中logpr ...
- loadrunner--TPS和平均事务响应时间
TPS就是每秒事务数,但是事务是基于虚拟用户数的,假如1个虚拟用户在1秒内完成1笔事务,那么TPS明显就是1:如果 某笔业务响应时间是1ms,那么1个用户在1秒内能完成1000笔事务,TPS就是100 ...
- mysql添加注释
-- 查看字段类型-- show columns from campaign_distribute --给表添加注释 -- alter table campaign_distribute commen ...
- sigint sigterm 有什么区别啊
SIGHUP 终止进程 终端线路挂断SIGINT 终止进程 中断进程SIGQUIT 建立CORE文件终止进程,并且生成core文件SIGILL 建立CORE文件 ...
- 2018.09.23 codeforces 1053A. In Search of an Easy Problem(gcd)
传送门 今天的签到题. 有一个很显然的结论,gcd(n∗m,k)≤2gcd(n*m,k)\le 2gcd(n∗m,k)≤2. 本蒟蒻是用的行列式求三角形面积证明的. 如果满足这个条件,就可以直接构造出 ...
- 2018.06.29 NOIP模拟 排列(线段树)
排列(premu.cpp) [题目描述] 对于一个 1 到 n 的排列,逆序数的定义为:排列中第 i 位 ai的逆序数就是 a1-ai-1中比 ai大的数的个数.另外用 pi表示 a1,-,ai的逆序 ...
- EF生成的SQL语句执行顺序问题。
//实体被更改后,再做删除,EF只生成删除语句 //实体删除后再更改,EF报错 //添加语句会再,更改,删除后执行,更AddObject位置无关 //一个实体多个字段被改,只会生成一句update / ...
- IntelliJ IDEA 2017版 spring-boot 实现jpa基本部署,通过实体类自动建立数据库
一.添加Spring Boot JPA-Hibernate步骤 1.在pom.xml添加mysql,spring-data-jpa依赖 2.在application.properties文件 ...
- VMware + LInux + Xshell 连接环境设置(心得体会)
准备好VMware软件,和Linux 和xshell三款软件,下载和安装好,这里VMware是十二,Linux是CentOs 6 ,xshell是5 其实没有什么区别只要版本兼容就行,我们就可以实现远 ...