数组:
优势:随机访问速度快,即 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个孩子的结点。
二叉树的前序、中序、后序
所谓的前、中、后都是以跟结点作为主体来说的。前序、也就是根节点放前面,优先选中,其他类推。