JAVA 自定义双链表实现(Links)

版权声明:转载请注明出处 https://blog.csdn.net/weixin_39554102/article/details/85274735

简介:

Links 接口模拟数据结构链表的操作, 继承了 Iterable 接口, 即可以foreach 循环;
Links 具体的操作 有 add、set、remove、get、size;是最为简单的实现

DoubleLinked 的实现参考自:jdk 1.8 LinkedList 实现;

如果对链表的更具体实现请看这:
LinkedList实现浅析

断开一个节点
在这里插入图片描述

接口: Links< E >

/**
 * <p> 链表的数据结构.包括 add、get、set、remove、size、iterator 方法,是一个极为简单的链表实现。
 * <p> 大部分逻辑参考了, jdk 1.8 LinkedList 的源码.
 * 
 * @author chenyq
 * @email [email protected]
 * @version 2018-12-26
 * @param <E>
 */
public interface Links<E> extends Iterable<E> {

	/**
	 * 添加元素
	 * @param e
	 * @return
	 */
	boolean add(E e);
	
	/**
	 * 获取指定索引的元素
	 * @param index
	 * @return
	 */
	E get(int index);
	
	/**
	 * 移除指定索引的元素
	 * @param index
	 * @return
	 */
	E remove(int index);
	
	/**
	 * 修改指定索引的元素
	 * @param index
	 * @param e
	 * @return
	 */
	E set(int index, E e);
	
	/**
	 * 获取元素总数量
	 * @return
	 */
	int size();
}

实现类: DoubleLinked

public class DoubleLinked<E> implements Links<E>, Serializable, Cloneable {

	/**
	 * 元素数量
	 */
	private int size;
	/**
	 * 记录第一个节点的指针.
	 */
	private Node<E> first;
	/**
	 * 记录了最后一个节点的指针
	 */
	private Node<E> last;
	/**
	 * 统计这个数据结构发生变化的次数, add / remove 操作会导致结构上的改变
	 */
	protected int modCount;
	
	/**
	 * 记录数据的节点
	 *
	 * @param <E>
	 */
	private static class Node<E> {
		private Node<E> prev;
		private E item;
		private Node<E> next;
		public Node(Node<E> prev, E item, Node<E> next) {
			super();
			this.prev = prev;
			this.item = item;
			this.next = next;
		}
	}
	
	/**
	 * 迭代器实现,
	 *
	 */
	private class LinkItr implements Iterator<E> {

		/**
		 * 最后返回的节点指针, 初始为null
		 */
		private Node<E> lastReturn;
		/**
		 * 光标, 下一个节点索引
		 */
		private int cursor;
		/**
		 * 下一个返回的节点指针, 初始为 first 节点
		 */
		private Node<E> node;
		/**
		 * 判断是否被并发修改过的计数器
		 */
		private int expectedModCount = modCount;
		
		public LinkItr() {
			this.node = first;
		}
		
		@Override
		public boolean hasNext() {
			return cursor < size;
		}

		@Override
		public E next() {
			checkConcurrentModification();
			if(! hasNext())
				throw new NoSuchElementException();
			if (node == null) {
				throw new NoSuchElementException();
			}
			
//			E e = node.item;
			lastReturn = node;
			node = node.next;
			cursor++;
			return lastReturn.item;
		}
		
		@Override
		public void remove() {
			if (lastReturn == null) {
				throw new NoSuchElementException();
			}
			unlink(lastReturn);
			this.expectedModCount = modCount;
			lastReturn = null;
			cursor--;
		}

		void checkConcurrentModification() {
			if (expectedModCount != modCount) {
				throw new ConcurrentModificationException();
			}
		}
	}

	@Override
	public boolean add(E e) {
		Node<E> l = last;
		Node<E> newNode = new Node<E>(l, e, null);
		
		if (l == null) {
			first = last = newNode;
		} else {
			l.next = last = newNode;
		}
		size++;
		modCount++;
		return true;
	}

	@Override
	public E get(int index) {
		checkIndex(index);
		return node(index).item;
	}
	
	/**
	 * 检查索引是否越界
	 * @param index
	 */
	private void checkIndex(int index) {
		if (index >= size || index < 0)
			throw new IndexOutOfBoundsException("index out : " + index);
	}

	Node<E> node(int index) {
		Node<E> f = first;
		for(int i = 0; i < index; i++) {
			f = f.next;
		}
		return f;
	}

	@Override
	public E remove(int index) {
		checkIndex(index);
		return unlink(node(index));
	}
	
	/**
	 * 从链表中断开指定的节点;
	 * @param node
	 * @return
	 */
	E unlink(Node<E> node) {
//		if (node == null) {
//			return null;
//		}
		E e = node.item;
		Node<E> prev = node.prev;
		Node<E> next = node.next;
		
		// 交换头节指针
		if (prev == null) {
			first = next;
		} else {
			prev.next = next;
			node.prev = null;
		}
		
		// 交换尾节点指针
		if (next == null) {
			last = prev;
		} else {
			next.prev = prev;
			node.next = null;
		}
		
		node.item = null;
		size--;
		modCount++;
		return e;
	}

	@Override
	public E set(int index, E e) {
		Node<E> n = node(index);
		E oldValue = n.item;
		n.item = e;
		return oldValue;
	}
	
	@Override
	public Iterator<E> iterator() {
		return new LinkItr();
	}

	@Override
	public int size() {
		return size;
	}
	

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	@Override
	public String toString() {
		
		
		Iterator<E> it = iterator();
		while(!it.hasNext()) {
			return "[]";
		}
		StringBuilder sb = new StringBuilder();
		sb.append('[');
		while(true) {
			sb.append(it.next());
			if (! it.hasNext())
				return sb.append(']').toString();
			sb.append(",").append(' ');
		}
	}
	
	

}

测试:

public class LinksTest {

	private Links<String> links;
	
	@Before
	public void init() {
		this.links = new DoubleLinked<>();
		for(int i = 0; i < 10; i++)
			links.add("node- " + i);
	}
	
	@Test
	public void get() {
		System.out.println(links);
		System.out.println(links.get(0));
		System.out.println(links.get(2));
		System.out.println(links.get(links.size() - 1));
		System.out.println(links.get(links.size()));
	}
	
	@Test
	public void remove() {
		System.out.println(links);
		System.out.println(links.remove(0));
		System.out.println(links.remove(2));
		System.out.println(links.remove(links.size() - 1));
		System.out.println(links);
	}
	
	@Test
	public void set() {
		System.out.println(links);
		System.out.println(links.set(0, "node - *"));
		System.out.println(links.set(3, "node - *"));
		System.out.println(links.set(links.size() - 1, "node - *"));
		System.out.println(links);
	}
	
	@Test
	public void iterator_1() {
		Iterator<String> it = links.iterator();
		while(it.hasNext()) 
			System.out.println(it.next());
		System.out.println(links);
	}
	
	@Test
	public void iterator_2() {
		Iterator<String> it = links.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
			it.remove();
		}
		System.out.println(links);
	}
	
	@Test
	public void iterator_3() {
		Iterator<String> it = links.iterator();
		while(true) {
			System.out.println(it.next());
		}
	}
	
	@Test
	public void iterator_4() {
		Iterator<String> it = links.iterator();
		while(true) {
			it.remove();
		}
	}
}

源码下载:

实现代码
测试代码

如有谬误,欢迎指正…

猜你喜欢

转载自blog.csdn.net/weixin_39554102/article/details/85274735
今日推荐