Java数据结构:链表的简单实现

链表工作原理

在这里插入图片描述
问题1:虚拟结点的使用,为什么要使用虚拟结点?
虚拟结点就是C数据结构中所说的头结点,它的next指针指向第一个结点(当然Java中是没有指针的);使用了虚拟结点,在删除第一个结点时不会误删导致整个链表丢失,有利于维护链表。

问题2:链表中未使用数组,索引从何而来?
链表也是线性表,不论是逻辑顺序和存储顺序上,表中元素都是相邻的;所以我们可以从第一个结点开始到最后一个结点,给他指定一个索引来方便我们指定结点。

问题3:索引是如何在链表中进行移动的呢?
在链式存储结构中,我们通过next引用将结点连接起来,这样我们通过next引用的不断向后传递,索引随着next移动在链表中移动。

问题4:为什么使用内部类,来定义结点的数据结构?
在定义结点类时,不光使用内部类,同时利用 private 将结点类封装在链表中,将底层数据封装起来,留下接口给程序员使用,可以防止链表被破坏。

实现的方法

  • isEmpty():判断链表是否为空
  • contains(AnyType data):链表是否包含某个元素
  • getSize():获得链表中存储元素个数
  • getFirst():查询链表中的第一个元素
  • get(int idx):根据给定索引查询链表中的元素
  • getLast():查询链表中的最后一个元素
  • addFirst():链表的头插法
  • add(int idx, AnyType data):向指定索引位置插入元素
  • addLast():链表的尾插法
  • removeFirst():删除表头元素
  • remove(int idx, AnyType data):删除指定索引位置的元素
  • removeLast():删除表尾元素

具体代码实现

public class MyLinkedList <AnyType>{
	private Node head;
	private int size;
	private class Node{
		AnyType data;
		Node next;
		public Node() {
			data = null;
			next = null;
		}
		public Node(AnyType data, Node next) {
			this.data = data;
			this.next = next;
		}
	}
	public MyLinkedList() {
		head = new Node();
		size = 0;
	}
	public boolean isEmpty() {
		return head.next == null;
	}
	public boolean contains(AnyType data) {
		if(isEmpty()) {
			return false;
		}
		Node prev = head;
		while(prev.next != null) {
			prev = prev.next;
			if(prev.data == data)
				return true;
		}
		return false;
	}
	public int getSize() {
		return size;
	}
	public AnyType getFirst() {
		Node prev = head.next;
		return prev.data;
	}
	public AnyType get(int idx) {
		if(idx > size || idx < 0) {
			throw new IllegalArgumentException("不合法位置");
		}
		Node prev = head;
		for(int i = 0; i <= idx; i++) {
			prev = prev.next;
		}
		return prev.data;
	}
	public AnyType getLast() {
		return get(size-1);
	}
	public void addFirst(AnyType data) {
		Node node = new Node(data, head.next);
		head.next = node;
		size++;
	}
	public void add(int idx, AnyType data) {
		if(idx > size || idx < 0) {
			throw new IllegalArgumentException("不合法位置");
		}
		Node prev = head;
		for(int i = 0; i < idx; i++) {
			prev = prev.next;
		}
		Node node = new Node(data, prev.next);
		prev.next = node;
		size++;
	}
	public void addLast(AnyType data) {
		add(size, data);
	}
	public void removeFirst() {
		if(isEmpty())
			throw new IllegalArgumentException("空表无法进行删除操作");
		head = head.next;
		size--;
	}
	public void remove(int idx) {
		if(isEmpty() || idx >= size)
			throw new IllegalArgumentException("空表或者索引越界无法完成操作");
		Node prev = head;
		for(int i = 0; i < idx; i++) {
			prev = prev.next;
		}
		Node outNode = prev.next;
		prev.next = outNode.next;
		size--;
	}
	public void removeLast() {
		remove(size - 1);
	}
	public String toString() {
		StringBuilder strb = new StringBuilder();
		strb.append("链表:");
		strb.append("size = "+size+"\n");
		strb.append("[");
		Node prev = head;
		while(prev.next != null) {
			prev = prev.next;
			strb.append(prev.data);
			if(prev.next != null)
				strb.append(',');
		}
		strb.append("]");
		return strb.toString();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章