散列表:

  就像 字典的ABCD...Z的索引一样,它的索引是通过哈希函数计算的。到索引位置后,可以再通过链表、数组或者其他方式存数据。

链表特点:

  涉及到索引角标的增删改查操作,都需要先查到元素,然后才可以做其他操作,这种操作的复杂度是O(N);

     链表一般会定义头尾指针,头尾的增删很方便,很适合用于实现队列(只有首尾操作)。

  链表由于可以头插入和尾插入等等,所以实现逆序很方便,只需要遍历并进行依次头插入即可实现反转链表,也可以通过反转指针实现。

 1 public void reverse() {
 2      // temp 和next的位置像斐波那契一样在依次向后移动
 3     Node temp = first;
 4     last = first;
 5     Node next = temp.getNext();
 6     for(int i = 0; i < size - 1; i++) {
 7         Node nextNext = next.getNext();
 8         next.setNext(temp);
 9         temp = next;
10         next = nextNext;
11     }
12     first = temp;
13     last.setNext(null);
14 }
反转指针

动态链表:动态创建,长度不需要提前定死

静态链表:用数组模拟链表,数组内放包含数据和角标的对象,角标就代表着指针一样,主要用于不包含指针,引用的语言实现链表,不常用。

 

递归的空间复杂度:

若一个算法为递归算法,其空间复杂度为递归所使用的堆栈空间的大小,它等于一次调用所分配的临时存储空间的大小乘以被调用的次数。这个理解对吗?
快排的空间复杂度为o(logn)(最差为o(n)),这个我还能说得通。但归并排序的的栈的深度是确定的logn,每层都要申请大小为n的空间存储归并后的序列,为什么空间复杂度是o(n),而不是o(nlogn)?
这个是实现上的优化。你可以从始至终都只用一个O(N)的存储空间。每层递归都在这一个空间上做操作。而不是每层递归都去创建一个新的数组/vector/list....