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. POJ2279 Mr Young's Picture Permutations

    POJ2279 Mr Young's Picture Permutations 描述: 有N个学生合影,站成左对齐的k排,每行分别有N1,N2…NK个人,第一排站最后,第k排站之前.学生身高依次是1… ...

  2. EndNote登陆Web账号时解决不断询问用户名密码

    EndNote登陆Web账号时不断询问用户名密码怎么破?EndNote有个同步功能,在登陆Web账号时,EndNote不断的询问账号和密码,可是用户名和密码明明已经填写正确和完毕,就是登陆不上EndN ...

  3. css实现渐变

    .gradient{ background: -webkit-gradient(linear, 0 0, 0 100%, from(#8ca0d3), to(#375a9a)); /** Chrome ...

  4. yield return 的使用方法

    以下代码,返回List,list内容为大于60的项 public Form1() { InitializeComponent(); } private void Form1_Load(object s ...

  5. vs2017创建netcore项目,部署到linux的docker容器里面

    开发环境 1.win10下面安装VS2017 2.linux安装Ubuntu16.4系统 步骤: 第一步:linux安装docker容器 docker中文文档,里面有详解的docker介绍及讲解,建议 ...

  6. GIF图制作

    一.安装image 首先在cmd中敲入代码pip install imageio,以便制作动图 二.安装完之后便可读取gif了 在idle中输入代码 import imageio savename = ...

  7. lxml.html 中几种解析器的区别(转)

    原文地址:https://blog.csdn.net/chroming/article/details/77104874

  8. hive Getting Started

    Apache HiveThe Apache Hive™ data warehouse software facilitates reading, writing, and managing large ...

  9. Java - 关于子类父类的向上转型,向下转型

    以下Animal为父类,Dog,Cat作为子类,分别继承Animal class Animal{ public void shout(){ System.out.println("叫了一声& ...

  10. Git修改文件

    如果我们修改了本地的某个文件但是没有提交,这时我们用 $ git status可以看到提示,例如我在readme2.txt里面新加了一行,然后查看状态: git status命令可以让我们时刻掌握仓库 ...