數據結構與算法學習筆記02-單向鏈表

1 結構:List-》AbstractList-》ArrayList,LinkedList

package 鏈表;
public interface List<E> {
	//默認公共
	static final int ELEMENT_NOT_FOUND = -1;
	/**
	 * 清除所有元素
	 */
	void clear();
	/**
	 * 元素的數量
	 */
	int size();
	/**
	 * 是否爲空
	 */
	boolean isEmpty();
	/**
	 * 是否包含某個元素
	 */
	boolean contains(E element);
	/**
	 * 添加元素到尾部
	 * @param element
	 */
	void add(E element);

	/**
	 * 獲取index位置的元素
	 */
	E get(int index);

	/**
	 * 設置index位置的元素
	 */
	E set(int index, E element);
	/**
	 * 在index位置插入一個元素
	 */
	void add(int index, E element);

	/**
	 * 刪除index位置的元素
	 */
	E remove(int index);
	/**
	 * 查看元素的索引
	 */
	int indexOf(E element);
}
package 鏈表;

public abstract class AbstractList<E> implements List<E>{
	/**
	 * 元素的數量
	 */
	protected int size;
	/**
	 * 元素的數量 
	 */
	public int size() {
		return size;
	}
	/**
	 * 是否爲空
	 */
	public boolean isEmpty() {
		return size == 0;
	}
	//封裝報錯
		protected void outOfBounds(int index) {
			throw new IndexOutOfBoundsException("Index"+index+",Size:"+size);
		}
		protected void rangeCheck(int index) {
			if(index<0||index>=size) {
				outOfBounds(index);
			}
		}
		protected void rangeCheckForAdd(int index) {
			if(index<0||index>size) {
				outOfBounds(index);
			}
		}
		/**
		 * 是否包含某個元素
		 */
		public boolean contains(E element) {
			return indexOf(element)!=ELEMENT_NOT_FOUND;
		}
		/**
		 * 添加元素到尾部
		 */
		public void add(E element) {
			add(size,element);
		}
}
package 鏈表;
public class LinkedList<E> extends AbstractList<E>{
	// 因爲繼承自AbstractList,所以不需要:private int size;否則會報越界異常
	//頭結點
	private Node<E> first;
	private static class Node<E> {
		E element;
		Node<E> next;
		public Node(E element,Node<E> next) {
			this.element = element;
			this.next = next;
		}
	}
	public void clear() {
		size = 0;
		first = null;
	}
	public int size() {
		return size;
	}
	public boolean isEmpty() {
		return size == 0;
	}
	public boolean contains(E element) {
		return indexOf(element)!=ELEMENT_NOT_FOUND;
	}
	public E get(int index) {
		return node(index).element;
	}
	public E set(int index, E element) {
		Node<E> node = node(index);
		E oldE = node.element;
		node.element = element;
		return oldE;
	}
	public void add(int index, E element) {
		if(index == 0) {
			System.out.println("已進入");
			first = new Node<>(element, first);
		}else {
			Node<E> preNode = node(index-1);
			//將結點2插入結點1和結點3中間:先讓結點2指向結點3,然後讓結點1指向結點2!!!
			preNode.next = new Node<>(element, preNode.next);
		}
		size++;
	}
	public E remove(int index) {
		rangeCheck(index);
		Node<E> node = first;
		if (index == 0) {
			first = first.next;
		}else {
			Node<E> preNode = node(index-1);
			node = preNode.next;
			preNode.next = node.next;			
		}
		size--;
		return node.element;
	}
	public int indexOf(E element) {
		if(element==null) {
			Node<E> node = first;
			for (int i = 0; i < size; i++) {
				if (node.element == null) {return i;}
				node = node.next;
			}
		}else {
			Node<E> node = first;
			for(int i=0;i<size;i++) {
				if(element.equals(node.element)) return i;
				node = node.next;
			}
		}
		return ELEMENT_NOT_FOUND;
	}
	/**
	 * @Description:獲取index位置對應結點對象
	 */
	private Node<E> node(int index) {
		rangeCheck(index);
		Node<E> node = first;
		for (int i = 0; i < index; i++) {
			node = node.next;
		}
		return node;
	}

	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("size=").append(size).append(",[");
		Node<E> node = first;
		for (int i = 0; i < size; i++) {
			if(i!=0) {
				stringBuilder.append(",");
			}
			stringBuilder.append(node.element);
			node = node.next;
		}
		stringBuilder.append("]");
//		Node<E> node1 = first;
//		while(node1!=null) {
//			node1 = node1.next;
//		}
		return stringBuilder.toString();
	}
}
package 鏈表;
//消除警告
@SuppressWarnings("unchecked")

public class ArrayList<E> extends AbstractList<E>{
	/**
	 * 所有的元素
	 */
	private E[] elements;
	private static final int DEFAULT_CAPACITY = 10;
	//初始化數組
	public ArrayList(int capaticy) {
		capaticy = (capaticy<DEFAULT_CAPACITY)?DEFAULT_CAPACITY:capaticy;
		//因爲所有類都繼承自object,所以先new Object數組,再強轉
		elements = (E[])new Object[capaticy];
	}
	//無參數則默認大小爲10
	public ArrayList() {
		//調用有參的構造函數!!!
		this(DEFAULT_CAPACITY);
	}
	
	/**
	 * 清除所有元素
	 */
	public void clear() {
		for (int i = 0; i < size; i++) {
			elements[i] = null;
		}
		//不能用:elements = null; 因爲會斷掉數組(棧)指向堆的空間,堆內部東西會銷燬,每次都需要重新開闢空間。
		size = 0;
	}
	/**
	 * 獲取index位置的元素
	 */
	public E get(int index) {
		rangeCheck(index);
		return elements[index];
	}
	/**
	 * 設置index位置的元素
	 * @return 歷史的元素
	 */
	public E set(int index,E element) {
		rangeCheck(index);
		E old = elements[index];
		elements[index] = element;
		return old;
	}
	/**
	 * 在index位置插入一個元素
	 */
	public void add(int index,E element) {
		rangeCheckForAdd(index);
		ensureCapacity(size+1);
		for (int i = size-1; i >= index; i--) {
			elements[i+1] = elements[i];
		}
		elements[index] = element;
		size++;
	}
	/**
	 * 刪除index位置的元素
	 */
	public E remove(int index) {
		rangeCheck(index);
		E old =  elements[index];
		for (int i = index+1; i < size; i++) {
			elements[i-1] = elements[i];
		}
		elements[--size]=null;
		return old;
	}
	/**
	 * 查看元素的位置
	 */
	public int indexOf(E element) {
		if(element==null) {
			for (int i = 0; i < size; i++) {
				if (elements[i] == null) {
					return i;
				}
			}
		}else {
			for(int i=0;i<size;i++) {
				if(elements[i].equals(element)) return i;
			}
		}
		return ELEMENT_NOT_FOUND;
	}
	
	/**
	 * 數組轉換成字符串
	 */
	@Override
	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("size=").append(size).append(",[");
		for (int i = 0; i < size; i++) {
			if(i!=0) {
				stringBuilder.append(",");
			}
			stringBuilder.append(elements[i]);
//			if(i!=size-1) {
//				stringBuilder.append(",");
//			}
		}
		stringBuilder.append("]");
		return stringBuilder.toString();
	}
	
	
	
	/**
	 * @Description:保證容量至少有capacity
	 */
	private void ensureCapacity(int capacity) {
		int oldCapacity = elements.length;
		if(oldCapacity>=capacity) return;
		//新容量爲舊容量的1.5倍
		int newCapacity = oldCapacity+(oldCapacity>>1);
		E[] newElements = (E[])new Object[newCapacity];
		//將原數組的元素填入新數組
		for (int i = 0; i < size; i++) {
			newElements[i] = elements[i];
		}
		//原數組指向新數組
		elements = newElements;
		
		System.out.println("擴容:"+oldCapacity+"至"+newCapacity);
	}
}

2 虛擬頭結點:減少頭結點與其他結點操作差異

package 鏈表;
/**
 * 增加虛擬頭結點
 */
public class LinkedList2<E> extends AbstractList<E>{
	private Node<E> first;
	//虛擬頭結點
	public LinkedList2() {
		first = new Node<>(null, null);
	}
...
	public void add(int index, E element) {
		rangeCheckForAdd(index);
	    Node<E> preNode = index == 0?first:node(index-1);
		preNode.next = new Node<>(element, preNode.next);
		size++;
	}

	public E remove(int index) {
		rangeCheck(index);
		Node<E> preNode = index == 0?first:node(index-1);
		Node<E> node = preNode.next;
		preNode.next = node.next;			
		size--;
		return node.element;
	}
...
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章