LinkedList单链表实现
/*
* @Author: meowrain meowrain@126.com
* @Date: 2023-11-03 12:11:07
* @LastEditors: meowrain meowrain@126.com
* @LastEditTime: 2023-11-03 22:44:22
* @FilePath: \datastructureWithJava\project02_linklist\src\SingleLinkedList.java
* @Description: "单链表Java实现"
*/
/*
*
* 这个代码中,索引是从首元节点才开始算的,也就是首元节点索引为0,所以索引值是比size小1的
*
* */
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SingleLinkedList<E> implements Iterable<E> {
private static class Node<E> { // 静态内部类,声明节点
E val;
Node<E> next;
Node(E val) {
this.val = val;
}
}
private final Node<E> head, tail; // 声明头节点和尾节点
private int size;
public SingleLinkedList() { // 构造函数初始化头尾节点
this.head = new Node<>(null);
this.tail = new Node<>(null);
head.next = tail;
this.size = 0;
}
/* 增 */
public void addFirst(E element) {
Node<E> x = new Node<>(null);
x.val = element; // 创建要插入的节点
Node<E> temp = head.next; // 保存头节点的下一个节点
x.next = temp; // 让x的next指针指向head的下一个节点
head.next = x;// 让head的next指针指向新节点x
size++;// 然后让链表元素长度加1
}
public void addLast(E element) {
Node<E> x = new Node<E>(element);
Node<E> temp;
if (size - 1 >= 0) {
temp = getNode(size - 1);
} else {
temp = head;
}
x.next = tail;
temp.next = x;
size++;
}
public void add(int index, E element) {
checkPositionIndex(index);
// 判断特殊情况
if (index == size) {
addLast(element);
return;
}
Node<E> x = new Node<E>(element);
Node<E> p = getNode(index);
Node<E> temp;
if (index - 1 >= 0) {
temp = getNode(index - 1);
} else {
temp = head;
}
temp.next = x;
x.next = p;
size++;
}
/* 删除 */
public E removeFirst() {
if (isEmpty()) { //如果为空,抛出没有元素的异常
throw new NoSuchElementException();
}
Node<E> x = head.next; //保存头节点的下一个节点
head.next = head.next.next;//让头节点的next指针指向它的下下个节点
x.next = null; //让头节点的下一个节点的next指针指向null
size--; //删除元素,size - 1
return x.val; //返回头节点的下一个节点的val值
}
public E removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Node<E> x = getNode(size - 1);
Node<E> temp;
if (size - 2 >= 0) {
temp = getNode(size - 2);
} else {
temp = head;
}
temp.next = tail;
x.next = null;
size--;
return x.val;
}
public E remove(int index) { //删除指定索引位置的节点
/*
* 注意:这里删除节点是不包括头节点的,删的是首元节点
* 因为这个链表就是带头节点的链表,删节点也是删的非头节点
* index为0表示的要删除的是首元节点,1时为首元节点的下一个节点
* */
checkElementIndex(index); //检查索引是否合法
Node<E> p = getNode(index); //获取index索引位置的节点
Node<E> prev;
if (index - 1 >= 0) { //如果删除的index>=1,那要删除的就不是首元节点,是首元节点后面的节点
prev = getNode(index - 1);
} else { //否则,要删除的节点就是首元节点,这样的话,我们就把头节点的地址赋值给prev,此时prev 等同于 head
prev = head;
}
Node<E> next = p.next; //获取index索引位置节点的下一个节点
prev.next = next; //让前一个节点的next指针指向p节点的下一个节点
p.next = null; //然后让p节点的next指针指向null,断绝和原来链表的联系
size--;
return p.val;//返货删除的节点的val值
}
/* 查 */
public E getFirst() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Node<E> first = getNode(0);
return first.val;
}
public E getLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Node<E> last = getNode(size - 1);
return last.val;
}
public E get(int index) {
checkElementIndex(index);
Node<E> p = getNode(index);
return p.val;
}
/*改*/
public E set(int index, E element) {
checkElementIndex(index);
Node<E> p = getNode(index); //找到索引位置的节点
E oldVal = p.val; //存储旧值
p.val = element;//修改节点的val值
return oldVal;//返回旧值
}
/* 额外工具函数实现 */
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index)) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index)) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
private Node<E> getNode(int index) {
Node<E> p = head.next;
for (int i = 0; i < index; i++) {
p = p.next;
}
return p;
}
/* 合并链表 */
public static <E extends Comparable<E>> SingleLinkedList<E> mergeTwoLinkList(SingleLinkedList<E> list1, SingleLinkedList<E> list2) {
SingleLinkedList<E> newLinkList = new SingleLinkedList<>();
Node<E> p1 = list1.head.next;
Node<E> p2 = list2.head.next;
while (p1.val != null && p2.val != null) {
if (p1.val.compareTo(p2.val) > 0) {
newLinkList.addLast(p2.val);
p2 = p2.next;
} else {
newLinkList.addLast(p1.val);
p1 = p1.next;
}
}
while (p1.val != null) {
newLinkList.addLast(p1.val);
p1 = p1.next;
}
while (p2.val != null) {
newLinkList.addLast(p2.val);
p2 = p2.next;
}
return newLinkList;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
Node<E> p = head.next;
@Override
public boolean hasNext() {
return p != tail;
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
E val = p.val;
p = p.next; // 将指针移动到下一个节点
return val;
}
};
}
public void display() {
Node<E> current = head.next;
while (current != tail) {
System.out.print(current.val + " ");
current = current.next;
}
System.out.println();
}
}
Main函数测试
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
SingleLinkedList<Integer> list1 = new SingleLinkedList<>();
list1.addLast(1);
list1.addLast(3);
list1.addLast(5);
list1.addLast(7);
list1.addLast(9);
SingleLinkedList<Integer> list2 = new SingleLinkedList<>();
list2.addLast(2);
list2.addLast(4);
list2.addLast(6);
list2.addLast(8);
list2.addLast(10);
SingleLinkedList<Integer> mergedList = SingleLinkedList.mergeTwoLinkList(list1, list2);
mergedList.display();
// 1 2 3 4 5 6 7 8 9 10
}
}