LinkedList封装
LinkedList简单的封装
package com.cn.test.jihe.LinkedList; import java.util.NoSuchElementException; public class LinkedList { // 头结点
Node<Object> first;
// 尾指针
Node<Object> last;
private int size; // 记录要插入的元素的总数 LinkedList() { } /**
* 将指定元素添加到此列表的结尾。
*
* @param obj
* @return insert
*/
boolean add(Object obj) {
linkLast(obj);
return true;
} private void linkLast(Object obj) {
Node l = last;
Node<Object> newNode = new Node<Object>(l, obj, null);
last = newNode; // 记录下次要插入的前驱节点
if (l == null) {
first = newNode;
} else {
l.next = newNode;
}
size++;
} /**
* 在此列表中指定的位置插入指定的元素。
*
* @throws Exception
* insert
*/
void add(int index, Object element) throws Exception {
// 判断要插入的位置
rangeCheckIndex(index);
// 循环遍历要插入的位置
insertElement(index, element);
size++;
} private void insertElement(int index, Object element) {
int count = 0;
Node temp = first;
// 在头部进行插入
if (index == 0) {
if (temp != null) {
Node newNode = new Node(null, element, temp);
temp.prev = newNode;
first = newNode;
} else {
Node tempLast = last;
Node newNode = new Node(tempLast, element, null);
last = newNode;
first = newNode;
}
return;
}
// 在尾部进行插入
if (index != 0 && index == size) {
Node tempLast = last;
Node newNode = new Node(tempLast, element, null);
last = newNode;
tempLast.next = newNode;
return;
}
// 不是在头部或者尾部进行插入
while (temp != null) { //
if (count == index) {
// 找到要插入的位置 temp这个节点表示要插入的节点的位置
Node newNode = new Node(temp.prev, element, null);
newNode.prev.next = newNode;
temp.prev = newNode;
newNode.next = temp;
}
temp = temp.next;
count++;
} } private void rangeCheckIndex(int index) throws Exception {
if (index < 0 || index > size)
throw new Exception("下标越界");
} /**
* 返回列表中指定的元素
*
* @param index
* @return
* @throws Exception
* select
*/
Object get(int index) throws Exception {
rangeCheckOut(index);
Node temp = first;
int count = 0;
while (temp != null) {
if (count == index) {
return temp.item;
}
count++;
temp = temp.next;
}
return null;
} /**
* 返回此列表的第一个元素。
*
* @throws Exception
*/
Object getFirst() throws Exception {
Node temp = first;
if (temp == null) {
throw new Exception("该集合没有元素");
}
return temp.item;
} /**
* 返回最后一个元素
*
* @return
* @throws Exception
*
*/
Object getLast() throws Exception {
Node temp = last;
if (temp == null) {
throw new Exception("该集合没有元素");
}
return temp.item;
} /**
* 返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
*
* @param o
* @return
*/
public int indexOf(Object o) {
int count = 0;
Node temp = first;
if (o == null) {
while (temp != null) {
if (null == temp.item) {
return count;
}
count++;
temp = temp.next;
}
} else {
while (temp != null) {
if (o.equals(temp.item)) {
return count;
}
count++;
temp = temp.next;
}
}
return -1;
} /**
*
* 返回此列表中最后出现的指定元素的索引, 如果此列表中不包含该元素,则返回 -1。
*/
public int lastIndexOf(Object o) {
int index = size - 1;
if (null == o) {
for (Node temp = last; temp != null; temp = temp.prev) {
if (null == temp.item) {
return index;
}
index--;
}
} else {
for (Node temp = last; temp != null; temp = temp.prev) {
if (o.equals(temp.item)) {
return index;
}
index--;
}
}
return -1;
} public int size() {
return size;
} private void rangeCheckOut(int index) throws Exception {
if (index < 0 || index >= size) {
throw new Exception("下标越界" + index);
} } /**
* 删除 获取并移除此列表的头(第一个元素)。
*
* @throws Exception
*/
Object remove() throws Exception {
if (first == null) {
throw new Exception("链表为空");
}
Node oldNode = first;
first = oldNode.next;
if (first != null) {
first.prev = null;
} else {
last = null;
}
size--;
return oldNode.item;
} /**
* 移除此列表中指定位置处的元素。
*
* @param index
* @throws Exception
*/ Object remove(int index) throws Exception {
// 判断长度是否超限
rangeCheckOut(index);
// 确认要删除的节点
Node oldNode = getIndexNode(index);
unLinkNode(oldNode);
return oldNode.item;
} /**
* remove(Object o) 从此列表中移除首次出现的指定元素(如果存在)。
*/
boolean remove(Object o) {
// 列表是否有该元素 , 如果有返回该节点
Node oldNode = checkeElement(o);
if (oldNode != null) {
unLinkNode(oldNode);
return true;
}
return false;
} /**
* 移除并返回此列表的第一个元素
*
* @return
* @throws Exception
*/
Object removeFirst() throws Exception {
if (first == null) {
throw new Exception("linkedList is null");
}
Object oldValue = first.item;
first = first.next;
if (first == null) {
last = null;
} else {
first.next.prev = null;
}
size--;
return oldValue;
} /**
* 移除最后一个元素
*
* @return
*/
public Object removeLast() {
Node l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
} /**
* 将此列表中指定位置的元素替换为指定的元素。
*
* @param index
* @param element
* @return
* @throws Exception
*/
public Object set(int index, Object element) throws Exception {
// 判断要插入的索引的位置
rangeCheckOut(index);
// 获取要插入位置的节点
Node indexNode = getIndexNode(index);
Object oldValue = indexNode.item;
indexNode.item = element;
return oldValue;
} /**
* 返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组
*
* @return
*/
public Object[] toArray() {
Object[] result = new Object[size];
int count = 0;
for (Node temp = first; temp != null; temp = temp.next) {
result[count] = temp.item;
count++;
}
return result;
} private Object unlinkLast(Node l) {
final Object element = l.item;
Node prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
if (prev == null) {
first = null;
} else {
last.next = null;
} size--;
return l.item;
} private Node checkeElement(Object o) {
if (o == null) {
// 循环遍历链表
for (Node temp = first; temp != null; temp = temp.next) {
if (null == temp.item) {
return temp;
}
}
} else {
for (Node temp = first; temp != null; temp = temp.next) {
if (o.equals(temp.item)) {
return temp;
}
}
}
return null;
} /**
* 取消链表节点之间的关系
*
* @param oldValue
*/
private void unLinkNode(Node oldNode) {
Node beforeNode = oldNode.prev;
Node afterNode = oldNode.next;
if (beforeNode == null) {
// 要删除的节点是头节点
first = afterNode;
afterNode.prev = null;
}
if (afterNode == null) {
// 要删除的节点是尾节点
last = beforeNode;
beforeNode.next = null;
} if (beforeNode != null && afterNode != null) {
// 删除的非头节点和非尾节点 修改指针的位置
beforeNode.next = afterNode;
afterNode.prev = beforeNode;
}
size--;
} /**
* 找到要删除的节点
*
* @param index
*/
private Node getIndexNode(int index) {
if (index < (size >> 1)) {
// 删除节点的位置为链表的前半段
Node firstNode = first;
for (int i = 0; i < index; i++) {
firstNode = firstNode.next;
}
return firstNode;
} else {
Node lastNode = last;
for (int i = --size; i > index; i--) {
lastNode = last.prev;
}
return lastNode;
}
} private Object removeAfterNode(int index) {
// 首先迭代
int count = 0;
for (Node temp = first; temp != null; count++) {
if (index == count) {
// 找到要删除的节点进行删除
Object oldValue = temp.item;
Node previous = temp.prev;
Node after = temp.next;
previous.next = after; size--;
return oldValue;
}
temp = temp.next;
}
return null;
} /**
* 采用双链表
*/
private static class Node<Object> {
Object item;
Node<Object> next; // 下一个节点
Node<Object> prev; // 前驱节点 Node(Node<Object> prev, Object element, Node<Object> next) {
this.item = element;
this.next = next;
this.prev = prev;
} Node(Object item) {
this.item = item;
}
}
}
testCast
/* LinkedList list = new LinkedList();
list.add(1);
list.add(1, 2);
list.add(2);
list.add(3);
list.add(2,8);
list.add(0,4);
list.add(1,2);
list.add(0,8);
list.add(2);
list.add(5);
System.out.println(list.size());
// System.out.println(list);
Object first = list.getFirst();
System.out.println("fist=" + (int)first);
Object last = list.getLast();
System.out.println("last=" + (int)last);
int indexOf = list.indexOf(10);
System.out.println("indexof=" + indexOf);
int lastIndexOf = list.lastIndexOf(100);
System.out.println("lastIndex=" + lastIndexOf);
LinkedList list2 = new LinkedList();
list2.add(2);
Object remove = list2.remove();
for (int i=0; i<list.size();i++) {
System.out.print("i=" + (int)list.get(i) + " ");
}
Object remove = list.remove(0);
System.out.println("remove=" + remove);
list.add(130);
for (int i=0; i<list.size();i++) {
System.out.print("i=" + (int)list.get(i) + " ");
}
System.out.println();
list.remove(new Integer(4));
for (int i=0; i<list.size();i++) {
System.out.print("j1=" + (int)list.get(i) + " ");
}
System.out.println();
list.add(0,89);
list.add(8,129);
list.removeFirst();
list.removeFirst();
System.out.println("------------------");
for (int i=0; i<list.size();i++) {
System.out.print("j2=" + (int)list.get(i) + " ");
}
*/
LinkedList list2 = new LinkedList();
list2.add(new String("a"));
list2.removeFirst();
list2.add(new String("b"));
// list2.add(new String("c"));
// list2.remove(new String("c"));
list2.removeLast();
list2.add(new String("c"));
list2.add(new String("d"));
list2.removeLast();
// list2.removeLast();
list2.add(new String("f"));
list2.set(0, new String("222"));
list2.add(1, new String("14"));
//list2.removeLast();
for (int i=0; i<list2.size();i++) {
System.out.print("j3=" + (String)list2.get(i) + " ");
}
LinkedList封装的更多相关文章
- 使用linkedlist封装简单的先进先出队列
创建一个类Queue代表队列(先进先出),添加add(Object obj) 及get()方法, 并添加main()方法进行验证 思路: 使用LinkedList实现队列,在向LinkedList中添 ...
- LinkedList源码
1.介绍及注意事项 链表由Josh Bloch书写,属于Java集合框架中的一种,LinkedList实现的是双链表,实现了所有的链表操作,可能够实现所有元素(包括)的基本操作. 链表是非线程同步的, ...
- 集合类——Collection、List、Set接口
集合类 Java类集 我们知道数组最大的缺陷就是:长度固定.从jdk1.2开始为了解决数组长度固定的问题,就提供了动态对象数组实现框架--Java类集框架.Java集合类框架其实就是Java针对于数据 ...
- ArrayList、Vector、LinkedList源码
List接口的一些列实现中,最常用最重要的就是这三个:ArrayList.Vector.LinkedList.这里我就基于JDK1.7来看一下源码. public class ArrayList< ...
- 详解Java中ArrayList、Vector、LinkedList三者的异同点(转)
本文转自http://my.oschina.net/zzw922cn/blog/491631 一.ArrayList ArrayList是一个可以处理变长数组的类型,这里不局限于“数”组,ArrayL ...
- Java数据结构之表的增删对比---ArrayList与LinkedList之一
一.Java_Collections表的实现 与c不同Java已经实现并封装了现成的表数据结构,顺序表以及链表. 1.ArrayList是基于数组的实现,因此具有的特点是:1.有索引值方便查找,对于g ...
- Java集合源码学习(三)LinkedList分析
前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...
- 集合中list、ArrayList、LinkedList、Vector的区别、Collection接口的共性方法以及数据结构的总结
List (链表|线性表) 特点: 接口,可存放重复元素,元素存取是有序的,允许在指定位置插入元素,并通过索引来访问元素 1.创建一个用指定可视行数初始化的新滚动列表.默认情况下,不允许进行多项选择. ...
- ArrayList 与 LinkedList
ArrayList:数组结构,插入删除的效率低,查询的效率较高. LinkedList:链接数据结构,插入删除的效率较高,查询的效率低. 两者的使用 ArrayList:适合用作添加数据,做查询. L ...
随机推荐
- 恢复 MSSQL bak 文件扩展名数据(下)
恢复 MSSQL bak 文件扩展名数据 一.概念: RESTORE Statements (Transact-SQL) Restores backups taken using the BACKUP ...
- mysql高级内容
一. 简介 实体与实体之间有3种对应关系,这些关系也需要存储下来 在开发中需要对存储的数据进行一些处理,用到内置的一些函数 视图用于完成查询语句的封装 事务可以保证复杂的增删改操作有效 二. 关系 创 ...
- TCP的超时与重传
一.引言 对于每个TCP连接,TCP管理4个不同的定时器 重传定时器用于当希望收到另一端的确认. 坚持 (persist) 定时器使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口. 保活 (ke ...
- python2与python3差异,以及如何写两者兼容代码
1.路径差异: 绝对导入:跳过包内,直接搜索 sys.path ,在sys.path的基础上进行我们的模块搜索. 相对导入:先包内,再包外,再,,, python2是默认相对导入的,因此对于一般性的导 ...
- P01-Python中列表的复制问题
(1)使用=直接赋值 a = [1, 2, 3, [6, 7]] b = a 初始情况: a: [1, 2, 3, [6, 7]] b: [1, 2, 3, [6, 7]] ------------- ...
- 大数据-spark HA集群搭建
一.安装scala 我们安装的是scala-2.11.8 5台机器全部安装 下载需要的安装包,放到特定的目录下/opt/workspace/并进行解压 1.解压缩 [root@master1 ~]# ...
- 做point data的切面的时候的注意事项
正确的顺序应该是: 先导入cell data,再转换为point data,再做切面.结果如下: 如果这里导入cell data以后先做了切面再转换为point data,结果就是这样的: 很明显中间 ...
- redis的持久化相关操纵
一.redis数据持久化(数据保存在硬盘上) 1. 关系型数据库Mmysql持久化 任何增删改语句都是在硬盘上操作(安全) 断电,硬盘上数据还在 2.非关系型数据库 默认所有的增删改都是在内存中操作( ...
- thinkphp5.1的安装
首先,下载composer.建议选择全屏安装.参考资料https://docs.phpcomposer.com/00-intro.html.安装到c盘.这个跟之前nodejs一样,都是装c盘.大概是全 ...
- Docker部署Nginx应用(2)
Docker部署Nginx应用(2) 1.拉取Nginx镜像 [root@localhost ~]# docker pull nginx Using default tag: latest lates ...