如果数组中的数据是有序的,我们在某个位置插入一个新的元素时,就必须按照刚才的方法搬移 k 之后的数据。但是,如果数组中存储的数据并没有任何规律,数组只是被当作一个存储数据的集 合。在这种情况下,如果要将某个数组插入到第 k 个位置,为了避免大规模的数据搬移,我们还有 一个简单的办法就是,直接将第 k 位的数据搬移到数组元素的最后,把新的元素直接放入第 k 个位 置。
在特定场景下,在第 k 个位置插入一个元素的时间复杂度就会降为 O(1)。这个 处理思想在快排中会用。
删除
插入数据类似,我们要删除第 k 个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞,内存就不连续了。在某些特殊场景下,我们并不一定非得追求数组中数据的连续性。如果我们将多次删除操作集中在一起执行,这种就类似于Java虚拟中的标记清除。
publicclassListTest{ publicstaticvoidmain(String[] args){ ArrayList<Integer> list = new ArrayList(10000); for (int i = 0; i < 10000; ++i) { list.add(i); } System.out.println(list); } }
// 获取index索引位置的元素 public E get(int index){ if(index < 0 || index >= size) thrownew IllegalArgumentException("Get failed. Index is illegal."); return data[index]; }
// 修改index索引位置的元素为e publicvoidset(int index, E e){ if(index < 0 || index >= size) thrownew IllegalArgumentException("Set failed. Index is illegal."); data[index] = e; }
// 查找数组中是否有元素e publicbooleancontains(E e){ for(int i = 0 ; i < size ; i ++){ if(data[i].equals(e)) returntrue; } returnfalse; }
// 查找数组中元素e所在的索引,如果不存在元素e,则返回-1 publicintfind(E e){ for(int i = 0 ; i < size ; i ++){ if(data[i].equals(e)) return i; } return -1; }
// 从数组中删除index位置的元素, 返回删除的元素 public E remove(int index){ if(index < 0 || index >= size) thrownew IllegalArgumentException("Remove failed. Index is illegal.");
E ret = data[index]; for(int i = index + 1 ; i < size ; i ++) data[i - 1] = data[i]; size --; data[size] = null; // loitering objects != memory leak