数组
定义:
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
数组优点:支持随机访问,根据下标随机访问的时间复杂度为 O(1)。
数组的操作:
查找:如果数组已排序,利用二分查找,时间复杂度为logn,否则顺序查找,时间复杂度为N。
public int rank(int key, int []a ){ int lo = 0; int hi = a.length - 1; while (lo <= hi){ int mid = lo + (hi - lo)/2; if (key < a[mid]) hi = mid -1; else if(key > a[mid]) lo = mid +1; else return mid; } return -1; }
插入:
数组为了保持内存数据的连续性,会导致插入、删除这两个操作比较低效。
假设数组的长度为 n,现在,如果我们需要将数据插入到数组中的第 k 个位置,我们需要先将第 k~n 的元素都顺序地往后挪一位。
如果在数组的末尾插入元素,那就不需要移动数据了,这时时间复杂度为 O(1)。但如果在数组的开头插入元素,那所有的数据都需要依次往后移动一位,所以最坏时间复杂度是 O(n)。 因为我们在每个位置插入元素的概率是一样的,所以平均情况时间复杂度为 (1+2+...n)/n=O(n)。
如果数组中的数据是有序的,我们在某个位置插入一个新的元素时,就必须按照刚才的方法搬移 k 之后的数据。但是,如果数组中存储的数据并没有任何规律,数组只是被当作一个存储数据的集合。在这种情况下,如果要将某个数据插入到第 k 个位置,为了避免大规模的数据搬移,我们还有一个简单的办法就是,直接将第 k 位的数据搬移到数组元素的最后,把新的元素直接放入第 k 个位置。
删除:
跟插入数据类似,如果我们要删除第 k 个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞。和插入类似,如果删除数组末尾的数据,则最好情况时间复杂度为 O(1);如果删除开头的数据,则最坏情况时间复杂度为 O(n);平均情况时间复杂度为 O(n)。
参考链接:
《算法4》