剑指offer55
思路 1、树的后序遍历 / 深度优先搜索往往利用 递归 或 栈 实现,本文使用递归实现。
思路:此树的深度和其左(右)子树的深度之间的关系:此树的深度 等于 左子树的深度 与 右子树的深度 中的 最大值 +1
思路 2、树的层序遍历 / 广度优先搜索往往利用 队列 实现。
思路:每遍历一层,则计数器 +1,直到遍历完成,则可得到树的深度。
具体实现:创建一个计数器res,用来记录层数;创建一个queue,存储每一层的所有node;每遍历一层,res+1;直到queue中不再有节点,即queue==null,终止遍历。因为需要频繁的增删,选择linkedlist。
结论:LinkedList是一种常用的数据容器,与ArrayList相比,LinkedList的增删操作效率相对较高,而查改操作效率较低。
1、LinkedList是通过双向链表实现的,创建LinkedList时,存入了首尾节点first last以及链表长度size,可以直接调用。
LinkedList结构:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable{
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
public LinkedList() {
}
/**
* Constructs a list containing the elements of the specified collection,
* in the order they are returned by the collection's iterator.
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
}
Node结构:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
读写(改查)效率低:
查:get(int index)
get(int index)方法是通过**node(int index)**来实现的,它的实现机制是比较传入的索引参数index与集合长度size/2,如果是index小,那么从第一个节点顺序循环,直到找到为止;如果index大,那么从最后一个倒序循环,直到找到为止。越靠近中间的元素,调用get(int index)方法执行的次数越多,效率也就越低。
因此在使用LinkedList的时候,我们不建议使用这种方式读取数据,可以使用getFirst(),getLast()方法,将直接用到类中的first和last变量。
改类似:set(int index, E element)
增删效率高:
增:add(E e) 和 add(int index, E element);
add(E e) 新建一个Node实体,同时指定其prev和next
add(int index, E element),与add(E e)不同的是,需要先调用**node(int index)**通过传入的index来定位到要插入的位置(返回当前索引对应的node,调用了LinkedList的查找方法,这个方法也比较耗时)。
但是它省去了ArrayList插入数据可能的数组扩容和数据元素移动时所造成的开销,插入效率高是相对的。
删除类似: remove(Object o)和remove(int index).
常用方法:
读写
增删
遍历:三种方法:普通for循环,增强for循环,Iterator迭代器
Java集合 LinkedList的原理及使用
2、ArrayList
(待)