数据结构(一):表List的简介及其两种实现方式

本文介绍了数据结构中的表List,包括ArrayList和LinkedList两种实现方式。ArrayList以数组为基础,适合快速读取,但插入删除操作较慢;而LinkedList利用链表结构,插入删除高效,但读取速度相对较慢。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表List是一种一维的数据结构,底层有两种实现方式,分别是基于数组实现的ArrayList和基于链表实现的LinkedList。ArrayList具有读取快(get),插入删除慢(add、remove)的特点;而LinkedList在知道插入删除的位置时,具有插入删除快(add、remove),而读取慢(get)的特点。

一、基于数组的实现

下面的代码是基于数组实现的一个List。

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyArrayList<Item> implements Iterable<Item> {

    private static final int DEFAULT_CAPACITY = 10;
    private Item[] items;
    private int size;
	
    public MyArrayList() {
	clear();
    }
	
    public void add(Item item) {
	add(size, item);
    }
	
    public void add(int i, Item item) {
	if(i < 0 || i > size)
	    throw new ArrayIndexOutOfBoundsException();
	if(size == items.length) {
	    ensureCapacity(size * 2 + 1);
	}
	for(int j=size;j>i;j--) {
	    items[j] = items[j-1];
	}
	items[i] = item;
	size++;
    }
	
	
    public Item remove(int i) {
	if(i < 0 || i >= size)
	    throw new ArrayIndexOutOfBoundsException();
	Item item = items[i];
	for(int j=i;j<size-1;j++) {
	    items[j] = items[j+1];
	}
	items[size-1] = null;
	size--;
	if(size < items.length/4 && items.length/2 > DEFAULT_CAPACITY)
	    ensureCapacity(items.length/2);
	return item;
    }
	
    public Item set(int i, Item item) {
	if(i < 0 || i >= size)
	    throw new ArrayIndexOutOfBoundsException();
	Item old = items[i];
	items[i] = item;
	return old;
    }
	
    public Item get(int i) {
	if(i < 0 || i >= size)
            throw new ArrayIndexOutOfBoundsException();
	return items[i];
    }
	
    public int size() {
	return size;
    }
	
    public boolean isEmpty() {
	return size == 0;
    }
	
    public void clear() {
	size = 0;
	ensureCapacity(DEFAULT_CAPACITY);
    }
	
    public void trimToSize() {
	ensureCapacity(size);
    }

    private void ensureCapacity(int capacity) {
	if(capacity < size)
	    return;
	Item[] old = items;
	items = (Item[])new Object[capacity];
	for(int i=0;i<size;i++) {
	    items[i] = old[i];
	}
    }
	
    public Iterator<Item> iterator() {
	return new MyArrayListIterator();
    }
	
    private class MyArrayListIterator implements Iterator<Item> {
		
	int current = 0;
	public boolean hasNext() {
       	    return current < size;
        }

        public Item next() {
	    if(!hasNext())
	        throw new NoSuchElementException();
	    return items[current++];
        }
    }
}

二、基于链表的实现

下面是基于双向链表的实现。为了便于特殊情况的处理,在链表的首尾两端各自添加了一个起标记作用的哑节点。

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyLinkedList<Item> implements Iterable<Item> {
	
    private int size;
    private Node startMarker;
    private Node endMarker;
	
    private class Node {
	Item item;
	Node prev;
	Node next;
		
	Node(Item item, Node prev, Node next) {
	    this.item = item;
	    this.prev = prev;
	    this.next = next;
	}
    }

    public MyLinkedList() {
	startMarker = new Node(null, null, null);
	endMarker = new Node(null, startMarker, null);
	startMarker.next = endMarker;
	size = 0;
    }
	
    public int size() {
	return size;
    }
	
    public boolean isEmpty() {
	return size == 0;
    }
	
    public void add(Item item) {
	add(size, item);
    }
	
    public void add(int i, Item item) {
	Node n = getNode(i, 0, size);
	addBefore(n, item);
    }
	
    private void addBefore(Node n, Item item) {
	Node newNode = new Node(item, n.prev, n);
	newNode.prev.next = newNode;
	n.prev = newNode;
	size++;
    }
	
    public Item get(int i) {
	return getNode(i).item;
    }

    private Node getNode(int i) {
	return getNode(i, 0, size-1);
    }
	
    private Node getNode(int i, int low, int high) {
	if(i < low || i > high)
	    throw new IndexOutOfBoundsException();
	Node n;
        if(i < size/2) {
	    n = startMarker.next;
	    for(int j=0;j<i;j++) {
		n = n.next;
	    }
	} else {
	    n = endMarker;
	    for(int j=size;j>i;j--) {
		n = n.prev;
	    }
	}
	return n;
    }
	
    public Item set(int i, Item newItem) {
	Node n = getNode(i);
	Item old = n.item;
	n.item = newItem;
	return old;
    }
	
    public Item remove(int i) {
	Node n = getNode(i);
	return remove(n);
    }
	
    private Item remove(Node n) {
	n.prev.next = n.next;
	n.next.prev = n.prev;
	size--;
	return n.item;
    }
	
    public void clear() {
	startMarker.next = endMarker;
	endMarker.prev = startMarker;
	size = 0;
    }

    public Iterator<Item> iterator() {
	return new Iterator<Item>() {
		
	Node current = startMarker.next;
		
	public boolean hasNext() {
	    return current != endMarker;
	}

	public Item next() {
	    if(!hasNext())
		throw new NoSuchElementException();
		Item item = current.item;
		current = current.next;
		return item;
	    }
	};
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值