1 链表介绍
链表的分类:单链表,双链表,循环链表
- 链表:由链将一个个元素连接,每一个元素我们通常将其称之为Node 节点
- Node 节点:由两部分组成
数据值的变量
Node next 用来存放下一个节点的Node 对象
package com.example.demo;
import java.util.LinkedList;
public class TestLinkedList {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList(); //双向链表
linkedList.add(11);
linkedList.add(22);
linkedList.add(33);
System.out.println(linkedList);
}
}
- 链表和数组的区别
链表查询慢(因为链表没有索引),但是增删快,
2 自定义单向链表
设计接口
目的:为了体系的完整,以及代码的复用,设计出以下结构
需要实现的方法
public int size();
public boolean isEmpty();
public boolean contains(E element);
public void add(E element);
public E get(int index);
public E set(int index,E element);
public void add(int index, E element);
public E remove(int index);
public int indexOf(E element);
public void clear();
public String toStrin();
2.1 List 接口
包含共性的方法
package com.example.demo.dao;
// 将arryList 和LinkedList中共性方法进行抽取->保证体系的完整性
public interface List<E> {
int size();
boolean isEmpty();
boolean contains(E element);
void add(E element);
E get(int index);
E set(int index,E element);
void add(int index, E element);
E remove(int index);
int indexOf(E element);
void clear();
String toString();
}
2.2 AbstractList 抽象类
实现共性的方法,实现List
package com.example.demo.abstractclass;
import com.example.demo.dao.List;
public abstract class AbstractList<E> implements List<E> {
protected int size;
// 判断当前集合中是否有元素
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void add(E element) {
add(size,element);
}
//indexOf : 去寻找对应的元素,如果找到了返回元素的索引,如果没找到返回一个-1
public boolean contains(E element) {
return indexOf(element) != -1 ;
}
}
2.3 LinkedList实现
顺序:
- 定义结构
- get -> node
- indexOf(E element)
- set(int index, E element)
- clear()
- add
- remove
- toString
package com.example.demo.Linked;
import com.example.demo.abstractclass.AbstractList;
public class LinkedList<E> extends AbstractList<E> {
public Node<E> first;
private static class Node<E> {
Node<E> next;
E element;
public Node(Node next, E element) {
this.next = next;
this.element = element;
}
}
public E get(int index) {
checkElementIndex(index);
return node(index).element;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index)) {
throw new IndexOutOfBoundsException(": Index: " + index + ", Size: " + size);
}
}
private boolean isElementIndex(int index) {
// 满足条件
return index >= 0 && index < size;
}
private Node<E> node(int index) {
Node x = first;
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
}
public E set(int index, E element) {
// 你在指定索引上去修改元素值是 element ,原来返回原来的值
checkElementIndex(index);
Node<E> node = node(index);
//记录原来的老值
E oldElement = node.element;
//将传入的值进行覆盖
node.element = element;
return oldElement;
}
public void add(int index, E element) {
checkPostionIndex(index); // 0 index >= 0
// 1. 获得 index -1 的Node 同时 还要获得 index 节点 去改变index- 1 上的next ,同时去 将next 节点的内存值 赋值给 新new 出来的Node
if (index == 0) {
first = new Node(first, element);
} else {
Node<E> pre = node(index - 1);
Node<E> next = pre.next;
pre.next = new Node<E>(next, element);
}
size++;
}
private void checkPostionIndex(int index) {
if(!isPostionIndex(index)){
throw new IndexOutOfBoundsException(": Index: " + index + ", Size: " + size);
}
}
private boolean isPostionIndex(int index) {
return index >= 0 && index <= size;
}
public E remove(int index) {
checkElementIndex(index);
Node<E> oldNode = first;
if(index == 0){
first = first.next;
}else {
Node<E> pre = node(index - 1);
oldNode = pre.next;
pre.next = oldNode.next;
}
return oldNode.element;
}
public int indexOf(E element) {
Node x = first;
int index = 0;
if (element == null) {
for (Node i = x; i != null; i = i.next) {
if(element == i.element)
{
return index;
}
index++;
}
} else {
for (Node i = x; i != null; i = i.next) {
if( element.equals(i.element)){
return index;
}
index ++;
}
}
return -1;
}
public void clear() {
size =0;
first=null;
}
public String toString(){
if(size == 0){
return "[]";
}
StringBuilder sb = new StringBuilder().append("[");
Node x = first;
for(Node i = x; i != null ; i = i.next){
sb.append(i.element);
if( i.next == null){
return sb.append("]").toString();
}
sb.append(",");
}
return sb.toString();
}
}
2.4 测试结果如下
package com.example.demo;
import com.example.demo.Linked.LinkedList;
public class TestLinkedList {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList(); //双向链表
linkedList.add(11);
linkedList.add(22);
linkedList.add(33);
System.out.println(linkedList);
}
}