數組:
優勢:隨機訪問速度快,即 int[] array={3,6,9,7,4} 可以使用array[下標] 隨便訪問第任意個元素,而鏈表只能訪問相鄰元素,順序訪問。
單向鏈表、雙向鏈表原理
區別: 表頭爲空,表頭指向後續第一個節點,第一個節點指向第二個節點,由此類推。每一個節點依次指向下一個節點。 雙向鏈表每個節點指向前後2個節點。
實現(java,部分功能實現)
public class DoubleLinkList<T> { private int mCount; private DNode<T> mHead; public DoubleLinkList() { mHead = new DNode<>(null, null, null); mHead.prev = mHead.next = mHead; mCount = 0; } public int size() { return mCount; } public boolean isEmpty() { return this.mCount == 0; } /** * 獲取第index的節點 * * @param index * @return */ public DNode<T> getNode(int index) { if (index < 0 || index >= mCount) { throw new IndexOutOfBoundsException(); } //看節點所在位置,判斷是否正向查找 if (index <= mCount / 2) { DNode<T> node = mHead.next; for (int i = 0; i < index; i++) { node = node.next; } return node; } DNode<T> rnode = mHead.prev; int rindex = mCount - index - 1; for (int j = 0; j < rindex; j++) { rnode = rnode.prev; } return rnode; } public T getFirst() { return getNode(0).value; } public T getLast(){ return getNode(mCount-1).value; } public void insert(int index,T t) { if(index==0) { DNode<T> node=new DNode<>(t,mHead,mHead.next); mHead.next.prev=node; mHead.next=node; mCount++; return; } DNode<T> inode=getNode(index); DNode<T> tnode=new DNode<>(t,inode.prev,inode); inode.prev.next=tnode; inode.next=tnode; mCount++; return; } public void insertFirst(T t){ insert(0,t); } public void appendLast(T t) { DNode<T> node=new DNode<>(t,mHead.prev,mHead); mHead.prev.next=node; mHead.prev=node; mCount++; } public static class DNode<T> { public DNode prev; public DNode next; public T value; public DNode(T value, DNode prev, DNode next) { this.prev=prev; this.next=next; this.value=value; } } }
實現中參考jdk的LinkedList實現,看到了靜態內部類,回顧一下靜態內部類的用法。即,當類的外部類需要使用該類,而靜態內部類本身不需要引用外部成員,並且靜態內部類可以單獨初始化的場景下使用。
遞歸算法
通俗概念:遞歸算法就是直接或間接調用自己的算法。
二叉樹概念
樹可以分爲 完美二叉樹(perfect Binary tree):除了葉子結點之外的每一個結點都有2個孩子,每一層都被完全填充。
完全二叉樹(complete Binary tree):除了最後一層之外的每一層都被完全填充,並且所有結點都保持向左對齊。
完滿二叉樹(full Binary tree):除了葉子結點之外的每一個結點都有2個孩子的結點。
二叉樹的前序、中序、後序
所謂的前、中、後都是以跟結點作爲主體來說的。前序、也就是根節點放前面,優先選中,其他類推。