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 ...
随机推荐
- 2019中山大学程序设计竞赛(重现赛) Clumsy Keke
Problem Description Keke is currently studying engineering drawing courses, and the teacher has taug ...
- Linux centos 7安装
Linux 安装 本章节我们将为大家介绍Linux的安装. 本章节以 centos6.4 为例. centos 下载地址: 可以去官网下载最新版本:https://www.centos.org/dow ...
- Windows下使用DOS命令进入MySQL数据库
先要配置环境变量 MYSQL_HOME : D:\mysql-8.0.11-winx64 Path:%MYSQL_HOME%\bin 1)新建MYSQL_HOME变量,并配置:C:\Program F ...
- 2016级算法第三次上机-G.Winter is coming
904 Winter is coming 思路 难题.首先简化问题, \(n\) 个0与 \(m\) 个1排成一列,连续的0不能超过x个,连续的1不能超过y个,求排列方法数. 显然会想到这是动态规划. ...
- Ubuntu16.04下编译OpenCV2.4.13静态库(.a文件)
Ubuntu16.04下编译OpenCV2.4.13静态库(.a文件) https://blog.csdn.net/woainishifu/article/details/79712110 我们在做项 ...
- 用Javac编译Java文件时出现“编码 GBK 的不可映射字符“的error
前提:JDK版本 >= 1.6会出现编译报错, 1.6前只会是警告 以下是javac的document: 遇到这种情况的原因是: 文件编码格式与编译器编译所选的encoding不同,有非英文字符 ...
- [LnOI2019]加特林轮盘赌
Luogu5249 轮流开枪打一个环上的人 , 每次\(p\)的概率打死 , \(p\)始终相同 , 从第\(1\)个人开始 , 求第\(k\)个人成为唯一幸存者的概率 \(19.3.30\) 官方题 ...
- python定义的一个简单的shell函数的代码
把写代码过程中经常用到的一些代码段做个记录,如下代码段是关于python定义的一个简单的shell函数的代码. pipe = subprocess.Popen(cmd, stdout=subproce ...
- BellmanFord贝尔曼-福特算法
import java.util.ArrayList; import java.util.Scanner; /** * 贝尔曼-福特算法 * * Bellman - ford算法是求含负权图的单源最短 ...
- Java 的多态
1 多态的概念 多态(?) 可以理解为多种状态/多种形态 同一事物,由于条件不同,产生的结果不同 程序中的多态 同一引用类型,使用不同的实例而执行结果不同的. 同:同一个类型,一般指父类. ...