目录
1.链表介绍
在Java中,链表是一种基本的数据结构,用于按照线性方式存储数据集合。与数组不同,链表中的元素在内存中不是连续存储的,而是通过指针(或引用)连接在一起。以下是链表的几个关键特点:
-
动态大小:链表的大小可以根据需要动态增长或缩小,不需要像数组那样预先定义固定的大小。
-
元素访问:链表不提供像数组一样的随机访问能力。访问链表中的元素通常需要从头开始遍历。
-
插入和删除操作:在链表中插入或删除元素通常比数组更快,特别是对于不是在链表末尾的操作,因为不需要移动其他元素来腾出空间或填补空位。
-
内存使用:链表的内存使用效率可能低于数组,因为除了存储数据外,链表的每个元素还需要额外的空间来存储指向下一个(及可能的上一个)元素的指针。
-
双向链表和单向链表:链表可以是单向的,每个节点只包含指向下一个节点的指针;也可以是双向的,每个节点包含指向上一个和下一个节点的指针。
-
实现:Java标准库提供了
LinkedList
类,实现了双向链表的功能。LinkedList
类继承自List
接口,因此可以使用List
接口提供的所有方法。 -
用例:链表通常用于实现队列、栈或其他需要快速插入和删除的场景。
2.链表的代码实现
1-这里我们需要先设置一个List接口,声明我们需要的方法
//<T> 是一个类型参数(Type Parameter),它用于定义一个泛型接口。使用泛型接口的主要原因是提供类型安全和灵活性
public interface List<T> {
void add(T value);
boolean remove(T value);
void insert(int index, T value);
void update(int index, T value);
T get(int index);
boolean contains(T value);
void display();
}
2-然后,我们实现一个MyLinkedList
类,这个类实现了我们自定义的List
接口
public class MyLinkedList<T> implements List<T> {
private Node<T> head;
private static class Node<T> {
T data;
Node<T> next;
Node(T data) {
this.data = data;
this.next = null;
}
}
@Override
public void add(T value) {
if(head == null){
head= new Node<>(value);
}else {
Node<T> current = head;
while(current.next != null){
current = current.next;
}
current.next = new Node<>(value);
}
}
@Override
public boolean remove(T value) {
if(head == null){
return false;
}
if(head.data.equals(value)){
head = head.next;
return true;
}else{
Node<T> current = head;
while(current.next != null){
if(current.next.data.equals(value)){
current.next = current.next.next;
return true;
}
current = current.next;
}
return false;
}
}
@Override
public void insert(int index, T value) {
if(index == 0){
Node<T> newNode = new Node<>(value);
newNode.next = head;
head= newNode;
return;
}
Node<T> current = head;
int currentlndex = 0;
while(current != null || currentlndex<index-1){
current = current.next;
currentlndex++;
}
if(current == null){
throw new IndexOutOfBoundsException("Index" + index + "out of bounds");
}
Node<T> newNode = new Node<>(value);
newNode.next = current.next;
current.next = newNode;
}
@Override
public void update(int index, T value) {
Node<T> current = head;
int currentIndex = 0;
while (current != null && currentIndex < index) {
if (currentIndex == index) {
current.data = value;
return;
}
current = current.next;
currentIndex++;
}
throw new IndexOutOfBoundsException("Index " + index + " out of bounds.");
}
@Override
public T get(int index) {
Node<T> current = head;
int currentIndex = 0;
while (current != null && currentIndex < index) {
current = current.next;
currentIndex++;
}
if (current == null) {
throw new IndexOutOfBoundsException("Index " + index + " out of bounds.");
}
return current.data;
}
@Override
public boolean contains(T value) {
Node<T> current = head;
while (current != null) {
if (current.data.equals(value)) {
return true;
}
current = current.next;
}
return false;
}
@Override
public void display() {
Node<T> current = head;
while (current != null) {
System.out.print(current.data + " -> ");
current = current.next;
}
System.out.println("null");
}
}
3-最后我们创建一个Test类来实现输出我们创建的方法
public class Test {
public static void main(String[] args) {
MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(1);
list.add(2);
list.add(3);
list.remove(2);
list.display();
}
}
4-结果(这里只举例remove这个方法)
1 -> 3 -> null