实现双向链表提供增删改查

MyLinkedList.java

  • 后期会添加更多操作
/**
 * 双向链表
 * 对外提供CRUD
 * 
 * 链表索引起点:0
 */
class MyLinkedList {

	private Node head;	// 头结点,可变化。管理链表的核心。
	private Node tail;	// 尾节点的引用。
	private int size;		// 链表节点的个数

	// 初始化
	public MyLinkedList() {
		head = new Node<>(null, null, null);
		tail = head;
		// head只有next会变
		// tail只有pre会变
		size = 0;
	}

	private boolean isNull() {
		return head == tail;
	}

	private void checkIndex(int pos) {
		if (pos >= size) {
			throw new RuntimeException("查询失败,越界的pos值:" + pos);
		}
	}

	// 遍历打印
	@Override
	public String toString() {
		// head不打印
		// if ! isNull printn(tail) else 不打印
		if (isNull()) {
			return "0 []";
		}
		StringBuilder sb = new StringBuilder(String.format("%d [", size));
		for (Node it = head.next; it.next != null; it = it.next) {
			sb.append(String.format("%s, ", it.data));
		}
		sb.append(String.format("%s]", tail.data));
		return sb.toString();
	}

	// 尾部追加
	public void append(T element) {
		// 分第一次和其他次
		if (tail.pre != null) {
			// System.out.println("并非第一次追加");
			Node node = new Node<>(tail, element, null);	// 新节点指向尾节点
			tail.next = node;	// 尾节点指向新节点
			tail = node;		// 设置新的尾节点
		} else {
			// System.out.println("第一次追加");
			Node node = new Node<>(head, element, null);	// 新节点指向第一个head
			head.next = node;	// 设置head的下一个是node
			tail = node;	// 设置新的tail
		}
		size++;
	}

	// 修改
	public void set(int pos, T element) {
		checkIndex(pos);
		Node it = head.next;	// iterator
		for (int i = 0; i < pos; i++) {
			it = it.next;
		}
		it.data = element;
	}

	// 查询
	public T get(int pos) {
		checkIndex(pos);
		Node it = head.next;
		for (int i = 0; i < pos; i++) {
			it = it.next;
		}
		return it.data;
	}

	// 插入
	public void insert(int pos, T element) {
		checkIndex(pos);
		Node it = head.next;	// iterator
		for (int i = 0; i < pos; i++) {
			it = it.next;
		}

		// it指向了要挪窝的节点
		Node node = new Node<>(it.pre, element, it);	// 新节点指向前后节点
		it.pre.next = node;	// it的前置节点的下一个节点不指it,改为指向node。
		it.pre = node;		// it的前置节点改为node

		size++;
	}

	// 删除
	public T delete(int pos) {
		checkIndex(pos);
		Node it = head.next;
		for (int i = 0; i < pos; i++) {
			it = it.next;
		}

		// it指向了要删除的节点。前后节点忽略IT。
		it.pre.next = it.next;
		it.next.pre = it.pre;

		T tmp = it.data;
		it = null;
		size--;
		return tmp;
	}
}

测试

public static void main(String[] args) {
	MyLinkedList list = new MyLinkedList<>();
	System.out.println(list);
	list.append(123);
	System.out.println(list);
	list.append(456);
	System.out.println(list);
	list.append(789);
	list.append(1);
	list.append(2);
	System.out.println(list);

	list.set(0, 111);	// pos 属于 [0, pos]
	System.out.println(list.size - 1);
	list.set(list.size - 1, 666);
	System.out.println(list);

	list.insert(3, 999999);
	System.out.println(list);
	list.insert(3, 8888);
	System.out.println(list);

	System.out.println(list.get(0));
	System.out.println(list.get(list.size - 1));

	System.out.println(list);
	System.out.println(list.delete(3));
	System.out.println(list);
}

输出

0 []
1 [123]
2 [123, 456]
5 [123, 456, 789, 1, 2]
4
5 [111, 456, 789, 1, 666]
6 [111, 456, 789, 999999, 1, 666]
7 [111, 456, 789, 8888, 999999, 1, 666]
111
666
7 [111, 456, 789, 8888, 999999, 1, 666]
8888
6 [111, 456, 789, 999999, 1, 666]

你可能感兴趣的:(Java,LinkedList)