java双向循环链表分析及其实现

ArrayList和LinkedList比较分析:

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.
对于随机访问getsetArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.
对于新增和删除操作addremoveLinedList比较占优势,因为ArrayList要移动数据。

4.ArrayList需要连续的存储空间,空间利用率较低,LinkedList空间利用率较高。

LinkedList图示(具体逻辑请参看代码和算法导论):



代码实现:

package 表;

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

// 带哨兵的双向循环链表
public class LinkedList<T> implements List<T>, Iterable<T> {
	// 节点类
	@SuppressWarnings("hiding")
	private class Node<T> {
		Node<T> pre;
		Node<T> next;
		T key;
		
		Node() {
			this.pre = this;
			key = null;
			this.next = this;
		}
		Node(Node<T> pre, T key, Node<T> next) {
			this.pre = pre;
			this.key = key;
			this.next = next;
		}
	}
	
	private int size = 0;          // 表中元素的数量
	private Node<T> guard = new Node<>();       // 哨兵节点
	private int modCount = 0;      // 记录list修改次数

	// 在表末尾加入元素
	@Override
	public void add(T obj) {
		add(size, obj);
	}

	// 在指定index处加入元素,如果index超出表范围,抛出异常
	@Override
	public void add(int index, T obj) {
		size = size + 1;
		Node<T> node = getNode(index);
		Node<T> newNode = new Node<>(node.pre, obj, node);
		node.pre.next = newNode;
		node.pre = newNode;
		modCount++;
	}

	// 删除链表中给定位置的元素,如果index超出表范围,抛出异常
	@Override
	public void remove(int index) {
		Node<T> node = getNode(index);
		node.pre.next = node.next;
		node.next.pre = node.pre;
		size--;
		modCount++;
	}

	// 删除表中遇到的第一个给定元素的值,如果表改变,则返回true,否则返回false
	@Override
	public boolean remove(T obj) {
		Node<T> node = guard.next;
		while(!node.key.equals(obj) && node.next != guard)
			node = node.next;
		if(node.key.equals(obj)) {
			node.pre.next = node.next;
			node.next.pre = node.pre;
			size--;
			modCount++;
			return true;
		}
		return false;
	}

	// 修改index处值为obj,如果index超出表范围,抛出异常
	@Override
	public void set(int index, T obj) {
		Node<T> node = getNode(index);
		modCount++;
		node.key = obj;
	}

	// 返回子list
	@Override
	public List<T> subList(int fromIndex, int lastIndex) {
		if(fromIndex < 0 || fromIndex > lastIndex || lastIndex > size)
			throw new IndexOutOfBoundsException();
		Node<T> from = getNode(fromIndex);
		List<T> result = new LinkedList<>();
		while(fromIndex < lastIndex) {
			result.add(from.key);
			from = from.next;
			fromIndex++;
		}
		return result;
	}

	// 返回index处的值,如果index超出表范围,抛出异常
	@Override
	public T get(int index) {
		check(index);
		return getNode(index).key;
	}
	// 返回index处节点,如果index超出表范围,抛出异常
	private Node<T> getNode(int index) {
		check(index);
		Node<T> node = guard.next;
		for(int i = 0; i < index; i++)
			node = node.next;
		return node;
	}

	// 返回表中元素个数
	@Override
	public int size() {
		return size;
	}

	// 判断表是否为空
	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	// 清空表中元素
	@Override
	public void clear() {
		// 清空表中对象
		for(Node<T> node = guard.next; node != guard;) {
			Node<T> delete = node;
			node = node.next;
			delete.pre = null;
			delete.key = null;
			delete.next = null;
		}
		guard.next = guard;
		guard.pre = guard;
		size = 0;
		modCount++;
	}

	// 返回迭代器
	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {
			private int index = 0;
			private int expectModCount = modCount;
			@Override
			public boolean hasNext() {
				return index < size;
			}

			@Override
			public T next() {
				checkForModification();
				if(!hasNext())
					throw new NoSuchElementException();
				Node<T> result = getNode(index);
				index++;
				return result.key;			
			}
			private void checkForModification() {
				if(expectModCount != modCount)
					throw new ConcurrentModificationException();
			}
		};
	}

	// 判断表中是否包含obj值
	@Override
	public boolean contains(T obj) {
		return indexOf(obj) != -1;
	}

	// 返回第一个值等于obj的index,如果表中不包含值obj,返回-1
	@Override
	public int indexOf(T obj) {
		Node<T> node = guard.next;
		int index = 0;
		while(node != guard && !node.key.equals(obj)) {
			node = node.next;
			index++;
		}
		if(node != guard)
			return index;
		return -1;
	}
	
	// 返回最后一个值等于obj的index,如果表中不包含值obj,返回-1
	@Override
	public int lastIndexOf(T obj) {
		Node<T> node = guard.pre;
		int index = size - 1;
		while(node != guard && !node.key.equals(obj)) {
			node = node.pre;
			index--;
		}
		return index;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		Node<T> next = guard.next;
		while(next != guard) {
			sb.append(next.key + ", ");
			next = next.next;
		}
		sb.delete(sb.length() - 2, sb.length());
		sb.append("]");
		return sb.toString();
	} 
	// 测试index是否超出表的范围,如果超出,抛出异常
	private void check(int index) throws IndexOutOfBoundsException{
		if(index >= size) 
			throw new IndexOutOfBoundsException();
	}

}


代码测试:

package 表;

public class TestList {
	public static void main(String[] args) {
		Integer[] iarray = new Integer[20];
		for(int i = 0; i < iarray.length; i++)
			iarray[i] = i;
		List<Integer> list = new LinkedList<>();
		// 测试add方法
		for(Integer i : iarray)
			list.add(i);
		System.out.println(list);
		list.add(2, 10);
		System.out.println(list);
		// 测试remove方法
		list.remove(2);
		System.out.println(list);
		list.remove(new Integer(10));
		System.out.println(list);
		// 测试set方法
		list.set(2, 11);
		System.out.println(list);
		// 测试subList
		System.out.println(list.subList(2, 10));
		// 测试get
		System.out.println(list.get(18));
		// 测试indexOf, lastIndexOf
		System.out.println("indexOf(): " + list.indexOf(11) +
				" lastIndexOf(): " + list.lastIndexOf(11));
		System.out.println("indexOf(): " + list.indexOf(111) +
				" lastIndexOf(): " + list.lastIndexOf(111));
		// 测试contains
		System.out.println("contains(4): " + list.contains(4) +
				" contains(100): " + list.contains(100));
		// 测试迭代器
		for(Integer i : list) {
			System.out.print(i + " ");
//			list.add(2 * i);      // 去掉注释会抛出异常,在迭代器调用时,不允许修改list
		}
		System.out.println();
		// 测试size,clear,isEmpty
		System.out.println("size(): " + list.size() + " isEmpty(): " + list.isEmpty());
		list.clear();
		System.out.println("调用clear()后\nsize(): " + list.size() + 
				" isEmpty(): " + list.isEmpty());	
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值