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封装的更多相关文章

  1. 使用linkedlist封装简单的先进先出队列

    创建一个类Queue代表队列(先进先出),添加add(Object obj) 及get()方法, 并添加main()方法进行验证 思路: 使用LinkedList实现队列,在向LinkedList中添 ...

  2. LinkedList源码

    1.介绍及注意事项 链表由Josh Bloch书写,属于Java集合框架中的一种,LinkedList实现的是双链表,实现了所有的链表操作,可能够实现所有元素(包括)的基本操作. 链表是非线程同步的, ...

  3. 集合类——Collection、List、Set接口

    集合类 Java类集 我们知道数组最大的缺陷就是:长度固定.从jdk1.2开始为了解决数组长度固定的问题,就提供了动态对象数组实现框架--Java类集框架.Java集合类框架其实就是Java针对于数据 ...

  4. ArrayList、Vector、LinkedList源码

    List接口的一些列实现中,最常用最重要的就是这三个:ArrayList.Vector.LinkedList.这里我就基于JDK1.7来看一下源码. public class ArrayList< ...

  5. 详解Java中ArrayList、Vector、LinkedList三者的异同点(转)

    本文转自http://my.oschina.net/zzw922cn/blog/491631 一.ArrayList ArrayList是一个可以处理变长数组的类型,这里不局限于“数”组,ArrayL ...

  6. Java数据结构之表的增删对比---ArrayList与LinkedList之一

    一.Java_Collections表的实现 与c不同Java已经实现并封装了现成的表数据结构,顺序表以及链表. 1.ArrayList是基于数组的实现,因此具有的特点是:1.有索引值方便查找,对于g ...

  7. Java集合源码学习(三)LinkedList分析

    前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...

  8. 集合中list、ArrayList、LinkedList、Vector的区别、Collection接口的共性方法以及数据结构的总结

    List (链表|线性表) 特点: 接口,可存放重复元素,元素存取是有序的,允许在指定位置插入元素,并通过索引来访问元素 1.创建一个用指定可视行数初始化的新滚动列表.默认情况下,不允许进行多项选择. ...

  9. ArrayList 与 LinkedList

    ArrayList:数组结构,插入删除的效率低,查询的效率较高. LinkedList:链接数据结构,插入删除的效率较高,查询的效率低. 两者的使用 ArrayList:适合用作添加数据,做查询. L ...

随机推荐

  1. 2019中山大学程序设计竞赛(重现赛) Clumsy Keke

    Problem Description Keke is currently studying engineering drawing courses, and the teacher has taug ...

  2. Linux centos 7安装

    Linux 安装 本章节我们将为大家介绍Linux的安装. 本章节以 centos6.4 为例. centos 下载地址: 可以去官网下载最新版本:https://www.centos.org/dow ...

  3. Windows下使用DOS命令进入MySQL数据库

    先要配置环境变量 MYSQL_HOME : D:\mysql-8.0.11-winx64 Path:%MYSQL_HOME%\bin 1)新建MYSQL_HOME变量,并配置:C:\Program F ...

  4. 2016级算法第三次上机-G.Winter is coming

    904 Winter is coming 思路 难题.首先简化问题, \(n\) 个0与 \(m\) 个1排成一列,连续的0不能超过x个,连续的1不能超过y个,求排列方法数. 显然会想到这是动态规划. ...

  5. Ubuntu16.04下编译OpenCV2.4.13静态库(.a文件)

    Ubuntu16.04下编译OpenCV2.4.13静态库(.a文件) https://blog.csdn.net/woainishifu/article/details/79712110 我们在做项 ...

  6. 用Javac编译Java文件时出现“编码 GBK 的不可映射字符“的error

    前提:JDK版本 >= 1.6会出现编译报错, 1.6前只会是警告 以下是javac的document: 遇到这种情况的原因是: 文件编码格式与编译器编译所选的encoding不同,有非英文字符 ...

  7. [LnOI2019]加特林轮盘赌

    Luogu5249 轮流开枪打一个环上的人 , 每次\(p\)的概率打死 , \(p\)始终相同 , 从第\(1\)个人开始 , 求第\(k\)个人成为唯一幸存者的概率 \(19.3.30\) 官方题 ...

  8. python定义的一个简单的shell函数的代码

    把写代码过程中经常用到的一些代码段做个记录,如下代码段是关于python定义的一个简单的shell函数的代码. pipe = subprocess.Popen(cmd, stdout=subproce ...

  9. BellmanFord贝尔曼-福特算法

    import java.util.ArrayList; import java.util.Scanner; /** * 贝尔曼-福特算法 * * Bellman - ford算法是求含负权图的单源最短 ...

  10. Java 的多态

    1    多态的概念 多态(?) 可以理解为多种状态/多种形态 同一事物,由于条件不同,产生的结果不同   程序中的多态 同一引用类型,使用不同的实例而执行结果不同的. 同:同一个类型,一般指父类. ...