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 ...
随机推荐
- 为什么在 js在 function($) 前面加分号
;function($,undefined) 是什么用处 ? ;(function($){$.extend($.fn... 现般在一些 JQuery 函数前面有分号 在前面加分号可以有多种用途: 1. ...
- [Flex] 组件Tree系列 —— 利用firstVisibleItem属性,设置或取得第一个显示节点
mxml: <?xml version="1.0" encoding="utf-8"?> <!--功能描述: 利用firstVisibleIt ...
- CiSCO 交换机配置 SSH 登陆
CiSCO 交换机配置 SSH 登陆 题目:在三层交换机上仅运行 SSH 服务,且用户名和密码的方式登录交换机. (一)了解主机名与域名 1."主机名" 为该设备的名称 2 ...
- 数据结构65:快速排序算法(QSort,快排)
上节介绍了如何使用起泡排序的思想对无序表中的记录按照一定的规则进行排序,本节再介绍一种排序算法——快速排序算法(Quick Sort). C语言中自带函数库中就有快速排序——qsort函数 ,包含在 ...
- SimpleITK学习(二)图像读取
通常我会用simpleitk来读取dicom文件,主要是为了将dicom文件转换为numpy矩阵,便于输入神经网络,读取dicom文件可分为两种情况,一.单独的dicom文件 二.一系列dicom文件 ...
- [Alpha]Scrum Meeting#1
github 本次会议项目由PM召开,时间为4月1日晚上10点30分 时长10分钟 任务表格 人员 昨日工作 下一步工作 木鬼 - 撰写初版技术规格说明书(issue#1) - 撰写初版功能规格说明书 ...
- train loss与test loss结果分析
train loss 不断下降,test loss不断下降,说明网络仍在学习; train loss 不断下降,test loss趋于不变,说明网络过拟合; train loss 趋于不变,test ...
- BZOJ - 3295 三维偏序 空间转换
题意:动态逆序对,共m次删除操作,求每次操作前的逆序对个数 删除操作转换为添加操作,首先对时间a进行简单排序 然后用cdq分治处理b维,树状数组处理c维 此时需要求的是对于某有序组\((a,b,c)\ ...
- redis的持久化相关操纵
一.redis数据持久化(数据保存在硬盘上) 1. 关系型数据库Mmysql持久化 任何增删改语句都是在硬盘上操作(安全) 断电,硬盘上数据还在 2.非关系型数据库 默认所有的增删改都是在内存中操作( ...
- 微信内置浏览器H5 弹出键盘 遮盖文本框解决办法 Fixed失效
if(/Android [4-6]/.test(navigator.appVersion)) { window.addEventListener("resize", functio ...