数组是用于存放一组数据,把这组数据存放在连续的空间里。通常有插入,删除,查找,访问等操作。
举例:
购物清单,初始状态:
清单:牛奶 -> 鸡蛋 -> 奶油 -> 火腿 -> 果汁
下标:0 1 2 3 4
插入:
1. 插在末尾
清单:牛奶 -> 鸡蛋 -> 奶油 -> 火腿 -> 果汁 -> 西红柿
下标:0 1 2 3 4 5
2. 插在中间
清单:牛奶 -> 鸡蛋 -> 奶油 -> 糖果 -> 火腿 -> 果汁 -> 西红柿
下标:0 1 2 3 4 5 6
删除:
1. 删除末尾
清单:牛奶 -> 鸡蛋 -> 奶油 -> 糖果 -> 火腿 -> 果汁
下标:0 1 2 3 4 5
2. 删除头部
清单:鸡蛋 -> 奶油 -> 糖果 -> 火腿 -> 果汁
下标:0 1 2 3 4
搜索:
一般需要遍历数字来做搜索,对于特殊的情况,可以优化,比如折半查找。
访问数组元素:
使用下标,直接访问。
代码实现,这里用的是Javascript。
// Create our array! let groceries = ["Milk", "Eggs", "Cereal", "Salami", "Juice"];// Access the first item let first = groceries[0];// Access the last item let last = groceries[groceries.length - 1];// Access the 3rd item let cereal = groceries[2];// Insert item at the end groceries.push("Potatoes");// Insert item at the beginning groceries.unshift("Ice Cream");// Insert item after the 3rd item groceries.splice(3, 0, "Cheese");// Remove last item groceries.pop();// Remove first item groceries.shift();// Delete the 3rd item groceries.splice(2, 1);// Find a particular item let foundIndex = groceries.indexOf("Eggs"); // 1// Iterate through each item let itemToFind = -1; for (let i = 0; i < groceries.length; i++) {let currentItem = groceries[i];if (currentItem == "Salami") {itemToFind = i; } }
数组和内存
数组会被分配在连续的内存中,初始化时,分配好内存。随着放入的元素越来越多,可能会达到初始分配最大值,这个时候系统会找到内存中另一块符合条件的连续空间,然后重新分配,并且把当前的数据copy到新分配的空间。所以,一旦有空间不够,需要重新分配的情况,开销可能会大。
时间复杂度
动作 | 平均复杂度 | 最坏复杂度 |
空间分配 | O(n) | O(n) |
随机访问 | O(1) | O(1) |
末尾插入 | O(1) | O(n) - 需要重新分配空间 |
非末尾插入 | O(n) | O(n) |
删除 | O(1) | O(n) |
末尾删除 | O(1) | O(1) |
线性搜索 | O(n) | O(n) |
二叉查找 | O(log n) | O(n) - 非排序数组 |