一.简介
计算机对数据存储方式有顺序存储、链式存储。数组是一种顺序存储的体现,链表是链式存储的体现,很多高级数据结构都是基于链表实现。
单向链表:数据元素通过一个指针指向下一个数据元素
二.实现
package com.vincent;
public class Main {
public static void main(String[] args) throws Exception{
LinkedList<Integer> list = new LinkedList<>();
for(int i=0;i<32;i++){
list.add(i);
}
System.out.println(list);
System.out.println(list.get(-2));
list.reverse();
System.out.println(list);
System.out.println(list.get(2));
list.remove(2);
System.out.println(list);
list.insert(0,100);
System.out.println(list);
}
}
class LinkedList<T> {
static class Node<T> {
T item;
Node<T> next;
public Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
@Override
public String toString() {
return item == null ? "null" : item.toString();
}
}
private Node<T> head;
private Node<T> rear;
private int size;
public void add(T item) {
if (head == null) {
head = new Node<>(item, null);
rear = head;
} else {
Node<T> node = new Node<>(item, null);
rear.next = node;
rear = node;
}
size++;
}
/**
* 获取指定位置节点,开始位置为0,索引支持负数,-1表示最后一个,-2表示倒数第2个
* @param index 节点索引
* @return
*/
private Node<T> nodeByIndex(int index){
int pos= (size + index) % size;
if(pos< 0 || pos >= size){
throw new IndexOutOfBoundsException();
}
Node<T> node = head;
for(int i=0;i<pos;i++){
node = node.next;
}
return node;
}
/**
* 获取指定位置节点元素,开始位置为0,索引支持负数,-1表示最后一个,-2表示倒数第2个
* @param index 节点索引
* @return
*/
public T get(int index){
Node<T> node = nodeByIndex(index);
return node.item;
}
public void insert(int index,T item){
Node<T> node = new Node<>(item,null);
if(index == 0){
node.next = head;
head = node;
rear = node;
}
else if(index == size){
rear.next = node;
rear = node;
}
else{
Node<T> prev = nodeByIndex(index-1);
node.next = prev.next;
prev.next = node;
}
size++;
}
public void remove(int index){
if(index == 0){
head = head.next;
if(size == 1){
rear = null;
}
}
else{
Node<T> node = nodeByIndex(index-1);
node.next = node.next.next;
node.next = null;
}
size--;
}
public void reverse(){
Node<T> pos = head;
Node<T> rst = null;
while(pos != null){
Node<T> next = pos.next;
pos.next = rst;
rst = pos;
pos = next;
}
head = rst;
}
public int size(){
return size;
}
@Override
public String toString() {
StringBuilder rst = new StringBuilder();
rst.append("[");
Node<T> pos = head;
while(pos != null){
rst.append(pos);
if(pos.next != null){
rst.append(",");
}
pos = pos.next;
}
rst.append("]");
return rst.toString();
}
}
效果:
三.总结
单向链表相对双向链表获取索引位置元素只能从头开始
双向链表可以从尾部向头部遍历,在获取指定索引处元素可以选择从头或从尾遍历,可以相对提高性能