数据结构和算法(五)LinkedList的底层实现

前言

     本章讲解顺序存储结构ArrayList的底层实现

方法

1.概念

我们知道,线性表的链式存储结构的实现在Java中是以LinkedList来实现的。那么我们用了这么久的LinkedList,如果不知道LinkedList的底层实现岂不是十分的滑稽,让我们来揭开它神秘的面纱。

2.实现思路

1)构建我们自己的List接口

我们可以尝试写出最基本的抽象方法。比如求集合中元素的个数方法等。

package cn.edu.ccut;
/**
 * 模仿List接口
 * @author wangjian
 *
 * @param <E>
 */
public interface List<E> {
	
	public int size();//获得集合长度
	
	public boolean add(E e);//新增对象
	
	public E get(int index);//获得对象
	
	public E remove(int index);//删除对象
	
	public boolean isEmpty();//判断集合是否为空
	
	public int indexOf(Object obj);//判断元素在集合中的位置
	
	public boolean contains(Object obj);//判断元素是否在集合中
}

2)编写具体的实现类LinkedList

package cn.edu.ccut;

public class LinkedList<E> implements List<E> {

	private int size;
	
	private Node<E> first;//当前链表的第一个节点
	
	private Node<E> last;//当前链表的最后一个节点
	
	//定义节点静态内部类
	private static class Node<E> {
        E item; //数据对象
        Node<E> next;//下一个节点
        Node<E> prev;//前一个节点

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
	
	@Override
	public int size() {
		return size;
	}

	@Override
	public boolean add(E e) {
		Node<E> l = last;//获取最后一个节点
		Node<E> newNode = new Node<>(l, e, null);//要添加的新节点
		last = newNode;
		if(l == null){//没有数据
			first = newNode;
		}else {
			l.next = newNode;//牵手最后一个节点
		}
		size++;
		return true;
	}
	
	private void checkIndexOfLink(int index){
		if( index < 0 || index > size-1){
			String error = "index: "+index+",size: "+size;
			throw new ArrayIndexOutOfBoundsException(error);
		}
	}

	@Override
	public E get(int index) {
		checkIndexOfLink(index);
		Node<E> currentNode = first;
		for (int i = 0; i < index; i++) {
			currentNode = currentNode.next;
		}
		return currentNode.item;
	}

	@Override
	public E remove(int index) {
		checkIndexOfLink(index);
		//获取要删除的节点
		Node<E> currentNode = first;
		for (int i = 0; i < index; i++) {
			currentNode = currentNode.next;
		}
		Node<E> currentPre = currentNode.prev;//当前节点的前驱
		Node<E> currentNext = currentNode.next;//当前节点的后继
		E currentItem = currentNode.item;//当前节点值
		if(currentPre == null){
			first = currentNext;//删除第一个元素无需拉手
		}else {
			currentPre.next = currentNext;//拉手
			currentNode.prev = null;//放手
		}
		if(currentNext == null){
			last = currentPre;//删除最后一个元素无需拉手
		}else {
			currentNext.prev = currentPre;//拉手
			currentNode.next = null;//放手
		}
		currentNode.item = null;//数据置空
		size--;
		return currentItem;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public int indexOf(Object obj) {
		int index = 0;
        if (obj == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (obj.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
	}

	@Override
	public boolean contains(Object obj) {
		return indexOf(obj) >= 0;
	}

}

请大家仔细体会代码的实现细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值