常见面试题手写双向循环链表

public class DoubleLink<E> {

	private class Node<E> {
		public E value; // 节点值
		public Node<E> prev; // 前一个节点
		public Node<E> next; // 后一个节点

		public Node(E value, Node<E> prev, Node<E> next) {
			this.value = value;
			this.prev = prev;
			this.next = next;
		}
	}

	private int size;// 链表长度
	public Node<E> head;// 头节点

	/**
	 * constructor
	 */
	public DoubleLink() {
		// 头节点不存储值
		head = new Node<E>(null, null, null);
		head.prev = head.next = head;
		size = 0;
	}

	/**
	 * 获取链表的长度
	 * 
	 * @return
	 */
	public int size() {
		return size;
	}

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

	/**
	 * 验证索引的合法性
	 * 
	 * @param index
	 */
	public void rangeCheck(int index) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException();
		}
	}

	/**
	 * 获取位置为index的节点
	 * 
	 * @param index
	 * @return
	 */
	private Node<E> getNode(int index) {
		rangeCheck(index);
		if (index <= size / 2) {
			Node<E> cur = head.next;
			for (int i = 0; i < index; i++) {
				cur = cur.next;
			}
			return cur;
		}
		Node<E> cur = head.prev;
		int newIndex = size - index - 1;
		for (int i = 0; i < newIndex; i++) {
			cur = cur.prev;
		}
		return cur;
	}

	/**
	 * 获取位置为index的节点值
	 * 
	 * @return
	 */
	public E get(int index) {
		return getNode(index).value;
	}

	/**
	 * 获取第一个节点的值
	 * 
	 * @return
	 */
	public E getFirst() {
		return getNode(0).value;
	}

	/**
	 * 获取最后一个节点的值
	 * 
	 * @return
	 */
	public E getLast() {
		return getNode(size - 1).value;
	}

	/**
	 * 插入节点
	 * 
	 * @param index
	 * @param value
	 */
	public void insert(int index, E value) {
		if (index == 0) {
			Node<E> cur = new Node<E>(value, head, head.next);
			head.next.prev = cur;
			head.next = cur;
			size++;
			return;
		}

		Node<E> node = getNode(index - 1);
		Node<E> cur = new Node<E>(value, node, head);
		node.next = cur;
		head.prev = cur;
		size++;
	}

	/**
	 * 添加到链表的头部
	 * 
	 * @param value
	 */
	public void addFirst(E value) {
		insert(0, value);
	}

	/**
	 * 添加节点到链表的尾部
	 * 
	 * @param value
	 */
	public void addLast(E value) {
		Node<E> cur = new Node<E>(value, head.prev, head);
		head.prev.next = cur;
		head.prev = cur;
		size++;
	}

	/**
	 * 删除位置为index的节点
	 * 
	 * @param index
	 */
	public void delete(int index) {
		rangeCheck(index);
		Node<E> cur = getNode(index);
		cur.prev.next = cur.next;
		cur.next.prev = cur.prev;
		size--;
		cur = null;
	}

	/**
	 * 删除第一个节点
	 */
	public void deleteFirst() {
		delete(0);
	}

	/**
	 * 删除最后一个节点
	 */
	public void deleteLast() {
		delete(size - 1);
	}

	public static void main(String[] args) {
		DoubleLink<Integer> dl = new DoubleLink<Integer>();
		// Node<Integer> n1 = new Node<Integer>(1, dl.head, dl.head);
		dl.insert(0, 1);
		dl.insert(1, 2);
		dl.insert(2, 3);
		dl.insert(3, 4);
		// dl.addFirst(5);
		// dl.addLast(6);
		dl.deleteLast();
		// System.out.println(dl.getLast());
		// dl.removeFirst();
		// System.out.println(dl.get(1));
		for (int i = 0; i < dl.size; i++) {
			System.out.print(dl.get(i) + " ");
		}
	}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值