LinkedList:
继承结构: LinkedList-> List ->Collection -> Iterable
简单实现:
文件:
MyNode:
package LinkedList;
// 元素类型是 Integer 类型(包装类)
public class MyNode {
public Long val;
public MyNode next; // 指向后继结点,尾结点的 next 是 null
public MyNode(Long val) {
this.val = val;
this.next = null;
}
}
MyList:
package LinkedList;
/*
自定义的线性表(以接口形式体现)
元素类型 Long
下标类型 int
*/
public interface MyList {
/**
* 返回线性表中的元素个数
*
* @return
*/
int size();
/**
* 将 e 尾插到线性表中,一定返回 true
*
* @param e
* @return
*/
boolean add(Long e);
/**
* 将 e 插入到线性表的 index 位置,从 [index, size()) 向后移
* index 的合法下标 [0, size()]
* 如果下标不合法:抛出一个 ArrayIndexOutOfBoundsException
*
* @param index
* @param e
*/
void add(int index, Long e);
/**
* 删除 index 位置的元素
* index 的合法下标:[0, size())
* 如果下标不合法:抛出一个 ArrayIndexOutOfBoundsException
*
* @param index
* @return 从线性表中删除掉的元素
*/
Long remove(int index);
/**
* 从前到后,删除第一个遇到的 e( equals() == true)
*
* @param e
* @return 删除成功:true,没有该元素:false
*/
boolean remove(Long e);
/**
* 直接返回 index 位置的元素
* index: [0, size())
*
* @param index
* @return
*/
Long get(int index);
/**
* 使用 e 替换 index 位置的元素
*
* @param index [0, size())
* @param e
* @return 原来 index 位置的元素
*/
Long set(int index, Long e);
/**
* 返回第一次遇到 e 的下标(equals() == true)
*
* @param e
* @return 如果没有找到,返回 -1
*/
int indexOf(Long e);
/**
* 从后往前,返回第一次遇到 e 的下标(equals() == true)
*
* @param e
* @return 如果没有找到,返回 -1
*/
int lastIndexOf(Long e);
/**
* 线性表中是否包含 e(equals)
*
* @param e
* @return
*/
boolean contains(Long e);
/**
* 清空线性表
*/
void clear();
/**
* 判断线性表是否是空的(empty) 等价于一个元素都没有
*
* @return
*/
boolean isEmpty();
}
MyLinkedList:
package LinkedList;
public class MyLinkedList implements MyList {
// 1. 链表的虚拟头结点
public MyNode dummyHead;
// 2. 链表的尾结点
public MyNode tail;
// 3. 维护着链表中的元素个数
public int size;
public MyLinkedList() {
this.dummyHead = new MyNode(-1l);
this.tail = dummyHead;
this.size = 0;
}
@Override
public int size() {
return size;
}
@Override
public boolean add(Long e) {
MyNode newNode = new MyNode(e);
tail.next = newNode;
tail = tail.next;
tail.next = null;
//更新size
size++;
return true;
}
@Override
public void add(int index, Long e) {
//判断越界
if (index < 0 || index > size) {
throw new ArrayIndexOutOfBoundsException("下标异常!");
}
//找到添加位置的前后两个结点
MyNode preNode = dummyHead;
MyNode curNode = dummyHead.next;
while (index-- > 0) {
preNode = preNode.next;
curNode = curNode.next;
}
//添加
MyNode newNode = new MyNode(e);
preNode.next = newNode;
newNode.next = curNode;
//判断一下是不是尾插 是的话更新一下尾
updateTail(curNode, newNode);
//更新size
size++;
}
@Override
public Long remove(int index) {
//判断是否越界
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException("下标异常!");
}
//找到要删除的结点curNode
MyNode preNode = dummyHead;
MyNode curNode = dummyHead.next;
while (index-- > 0) {
preNode = preNode.next;
curNode = curNode.next;
}
//删除
preNode.next = curNode.next;
//判断一下是不是尾删 是的话更新尾
updateTail(preNode.next, preNode);
//更新size
size--;
return curNode.val;
}
@Override
public boolean remove(Long e) {
//查找判断curNode.val是不是==e
MyNode preNode = dummyHead;
MyNode curNode = dummyHead.next;
while (curNode != null) {
if (curNode.val.equals(e)) {
preNode.next = curNode.next;
//更新size
size--;
//判断一下是不是尾删 是的话更新尾
updateTail(preNode.next, preNode);
return true;
}
preNode = preNode.next;
curNode = curNode.next;
}
return false;
}
@Override
public Long get(int index) {
//判断是否越界
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException("下标异常!");
}
MyNode curNode = dummyHead.next;
while (index-- > 0) {
curNode = curNode.next;
}
return curNode.val;
}
@Override
public Long set(int index, Long e) {
//判断是否越界
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException("下标异常!");
}
MyNode curNode = dummyHead.next;
while (index-- > 0) {
curNode = curNode.next;
}
Long res = curNode.val;
curNode.val = e;
return res;
}
@Override
public int indexOf(Long e) {
MyNode curNode = dummyHead.next;
int index = -1;
while (curNode != null) {
index++;
if (curNode.val.equals(e)) {
return index;
}
curNode = curNode.next;
}
return -1;
}
@Override
public int lastIndexOf(Long e) {
MyNode curNode = dummyHead.next;
int endIndex = -1;
int index = -1;
while (curNode != null) {
index++;
if (curNode.val.equals(e)) {
endIndex = index;
}
curNode = curNode.next;
}
return endIndex;
}
@Override
public boolean contains(Long e) {
MyNode curNode = dummyHead.next;
while (curNode != null) {
if (curNode.val.equals(e)) {
return true;
}
curNode = curNode.next;
}
return false;
}
@Override
public void clear() {
dummyHead.next = null;
tail = dummyHead;
size = 0;
}
@Override
public boolean isEmpty() {
return size == 0;
}
private void updateTail(MyNode flag, MyNode newTail) {
if (flag == null) {
tail = newTail;
}
}
public void printList() {
MyNode head = dummyHead.next;
while (head != null) {
System.out.print(head.val + " -> ");
head = head.next;
}
System.out.print("null");
}
}