package com.mayikt.linkedlistsource;
import com.mayikt.CustomerException;
/**
* 链表的获取
*
* @author zx
* @date 2022年01月27日 13:56
*/
public class LinkedListExt<E> {
//定义 first 、Node 标识结点,便于后期操作
/**
* 第一个节点
*/
transient Node<E> first;
/**
* 最后一个节点
*/
transient Node<E> last;
/**
* 链表中的个数
*/
transient int size = 0;
/**
* 链表的结点
*
* @param <E>
*/
private static class Node<E> {
E item;
Node<E> prev;
Node<E> next;
public Node(E item, Node<E> prev, Node<E> next) {
this.item = item;
this.prev = prev;
this.next = next;
}
}
/**
* 添加元素
*
* @param e 添加的元素
* @return true 表示添加成功
*/
public boolean add(E e) {
//添加到链表的末尾
addLinketLast(e);
return true;
}
private void addLinketLast(E e) {
//先假设 链表中已经有数据结点 ----final 防止引用被改变
final Node<E> temp = last;
//添加的结点都是往链表末尾添加,即next结点都为空
final Node<E> newNode = new Node<>(e, last, null);
//新添加的结点放到末尾。使用last结点记录末尾结点
last = newNode;
if (temp == null) {
//说明第一次添加
first = newNode;
} else {
//构建链表的关系
temp.next = newNode;
}
size++;
}
private void checkElementIndex(int index) {
if (!(index >= 0 && index < size)) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
public E get(int index) {
//检查索引是否越界
checkElementIndex(index);
return node(index).item;
}
//使用折半查找,此折 非比折
private Node<E> node(int index) {
if (index < (size >> 1)) {
//index 在 size/2 的 左边,从first 结点循环遍历去找 截止点位 size/2
Node<E> x = first;
//往下循环去找 first --->index
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
} else {
//从last循环遍历往上找, last ----> index
Node<E> x = last;
for (int i = size - 1; i > index; i--) {
x = x.prev;
}
return x;
}
}
public E remove(int index) {
//检查索引是否越界
checkElementIndex(index);
return unLinkedList(node(index));
}
private E unLinkedList(Node<E> currentNode) {
//改变链表引用关系
Node<E> currentPrev = currentNode.prev;
Node<E> currentNext = currentNode.next;
//如果是first 、last结点 分两个结点去改变引用
//如果删除的是firstNode
if (currentPrev == null) {
first = currentNext;
} else {
currentPrev.next = currentNext;
//释放了当前结点上一个结点的引用 ,还有下一个结点的引用没有释放
currentNode.prev = null;
}
//如果删除的是最后一个结点
if (currentNext == null) {
//说明删除的是最后一个结点
last = currentPrev;
} else {
currentNext.prev = currentPrev;
currentNode.next = null;
}
currentNode.item = null;
size--;
return currentNode.item;
}
public void showLinkedList() throws CustomerException {
checkLinkedListIsEmpty();
Node<E> temp = first;
while (true) {
System.out.println(temp.item);
if (temp.next == null) {
//链表遍历到最后了
break;
}
temp = temp.next;
}
}
/**
* 检查链表是否为空
*/
private void checkLinkedListIsEmpty() throws CustomerException {
if (first == null) {
throw new CustomerException("链表为空");
}
}
}
链表基本的增、删、查
最新推荐文章于 2025-08-04 22:37:45 发布