小肥柴慢慢学习数据结构笔记(Java篇)(2-1 单链表LinkedList)

小肥柴慢慢学习数据结构笔记(Java篇)(2-1 单链表LinkedList)

目录

小肥柴慢慢手写数据结构(C篇)(2-1 单链表 SingleLinkedList self版实现(1))中我们实现了C版的单链表,后又学习了反转、快慢指针等知识点,还对比了严版教材的实现,现在用Java再写一遍,练习OOP。
注:代码参考刘大佬的github

2-1 上代码

  1. MyLinkedList.java
public class MyLinkedList<E> {
	private Node DummyHead;
	private int size;

	private class Node {
		private E e;
		private Node next;

		public Node() {
			this(null, null);
		}

		public Node(E e) {
			this(e, null);
		}

		public Node(E e, MyLinkedList<E>.Node next) {
			this.e = e;
			this.next = next;
		}

		@Override
		public String toString() {
			return e == null ? null : e.toString();
		}
	}

	public MyLinkedList() {
		DummyHead = new Node();
		size = 0;
	}

	public int getSize() {
		return size;
	}

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

	public void add(int index, E e) {
		if (index < 0 || index > size)
			throw new IllegalArgumentException("Add failed. Illegal index.");

		Node prev = DummyHead;
		for (int i = 0; i < index; i++)
			prev = prev.next;

		/*
		 * 等价于 Node node = new Node(e); node.next = prev.next; prev.next = node;
		 */
		prev.next = new Node(e, prev.next);
		size++;
	}

	public void addFirst(E e) {
		add(0, e);
	}

	public void addLast(E e) {
		add(size, e);
	}

	public E get(int index) {
		if (index < 0 || index > size)
			throw new IllegalArgumentException("Get failed. Illegal index.");

		Node cur = DummyHead;
		for (int i = 0; i < size; i++)
			cur = cur.next;
		return cur.e;
	}

	public E getFirst() {
		return get(0);
	}

	public E getLast() {
		return get(size - 1);
	}

	public void set(int index, E e) {
		if (index < 0 || index > size)
			throw new IllegalArgumentException("Set failed. Illegal index.");

		Node cur = DummyHead;
		for (int i = 0; i < index; i++)
			cur = cur.next;
		cur.e = e;
	}

	public boolean contains(E e) {
		Node cur = DummyHead.next;
		while (cur != null) {
			if (cur.equals(e))
				return true;
			cur = cur.next;
		}
		return false;
	}

	public E remove(int index) {
		if (index < 0 || index >= size)
			throw new IllegalArgumentException("Remove failed. Index is illegal.");

		Node prev = DummyHead;
		for (int i = 0; i < index; i++)
			prev = prev.next;

		Node ret = prev.next;
		prev.next = prev.next.next;
		ret.next = null;
		size--;

		return ret.e;
	}

	public E removeFirst() {
		return remove(0);
	}

	public E removeLast() {
		return remove(size - 1);
	}

	public void removeElem(E e) {
		Node prev = DummyHead;
		while (prev.next != null) {
			if (prev.next.equals(e))
				break;
			prev = prev.next;
		}

		if (prev.next != null) {
			Node del = prev.next;
			prev.next = prev.next.next;
			del.next = null;
			del = null;
			size--;
		}
	}

	@Override
	public String toString() {
		StringBuilder strBld = new StringBuilder();
		Node cur = DummyHead.next;
		while (cur != null) {
			strBld.append(cur).append("->");
			cur = cur.next;
		}
		strBld.append("null");
		return strBld.toString();
	}
}

2-2 代码细节

  1. 将节点类型Node声明为私有内部类,隐藏实现,仅暴露给外部操作API。
  2. 丰富Node的构造函数,可以使用缺省值。
  3. 用Node的构造函数巧妙解决了节点插入问题中保留“下一个指向”的问题。
    Node node = new Node(e);
    node.next = prev.next;
    prev.next = node;
    等价于
    prev.next = new Node(e, prev.next);
  4. 时间复杂度上并没有太多讨论的点,只是需要注意链表是牺牲了随机访问的特性,换取了动态的特性,也就是插入和删除很容易,但是修改和查询没有动态数组ArrayList快。
  5. 还是OOP写起来顺手,哈哈哈。

2-3 源码阅读

网上源码解析的帖子很多,直接学习即可,注意JDK源码中使用双链表实现,且包含了E对象的null处理,即链表节点存在,但节点元素内容为空!
(参考) 《JAVA源码分析》:LinkedList.

2-4 总结

Java的LinkedList实现比较简单,思路非常清晰,在代码复用和接口设计上值得学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值