数组(Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。
一、数组的概念
数组(Array)是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。
在C语言中, 数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。
二、数组的特点
- 数组中的数组元素必须是同一种数据类型,可以是基本数据类型,也可以是引用数据类型;
- 数组中的每个数组元素可以通过下标来获取,下标从0开始,范围是[0,length-1];
- 在定义数组的时候,必须指定数组的大小,并且指定之后不能再修改其大小;
- 数组中的数组元素是有序的,这个有序指的并不是大小的排序,指的是插入的先后顺序;
- 数组是一种变量的集合,在这个集合中,所有变量的数据类型都是相同的;
- 每一个数组元素的作用相当于简单变量;
- 同一数组中的数组元素在内存中占据的内存空间是连续的;
- 数组的大小(数组元素的个数)必须在定义时确定,在程序中不可改变;
- 数组名代表的是数组在内存中的首地址。
三、数组的优缺点
优点:
- 按照索引查询元素速度快;
- 能存储大量数据;
- 按照索引遍历数组方便;
- 数组定义简单,而且访问很方便;
- 可以随机访问其中的元素。
缺点:
- 根据内容查找元素速度慢;
- 数组的大小一经确定不能改变,不适合动态存储;
- 数组智能存储一种类型的数据;
- 增加、删除元素效率慢;
- 未封装任何方法,所有操作都需要用户自己定义;
- 数组的空间必须是连续的,这就造成数组在内存中分配空间时必须找到一块连续的内存空间。所以数组不可能定义的太大,因为内存中不可能有那么多大的连续的内存空间,而解决这个问题的方法就是使用链表。
四、数组的常用操作
1、sort( [compareFunction] )
对数组进行排序。
var numbers = [2, 4, 1, 10, 3];
// 回调参数 a,b 是数组要比较的两个元素,a 排在 b 的前面。
numbers.sort(function(a, b){
// 当 a > b 时触发交换操作,把较小的排在前面,即升序。
return a - b;
});
> [1,2,3,4,10]
numbers.sort(function(a,b){
// 当 a < b 时触发交换操作,把较大的排在前面,即降序。
return b - a;
});
> [10,4,3,2,1]
2、join( [separator] )
将数组中的所有元素连接成一个字符串。separtor 用于指定连接每个数组元素的分隔符。分隔符会被转成字符串类型;如果省略的话,默认为一个逗号。如果separtor 是一个空字符串,那么数组中的所有元素将被直接连接。
var data = ['Wind', 'Rain', 'Fire'];
data.join(); // Wind,Rain,Fire
data.join(', '); // Wind, Rain, Fire
data.join(' + '); // Wind + Rain + Fire
data.join(''); // WindRainFire
3、concat( value1,…,valueN )
concat 方法将创建一个新的数组,然后将调用它的对象(this 指向的对象)中的元素以及所有参数中的数组类型的参数中的元素以及非数组类型的参数本身按照顺序放入这个新数组,并返回该数组, valueN 允许是数组或非数组值。在没有给 concat 传递参数的情况下,它只是复制当前数组并返回副本。
var alpha = ['a', 'b', 'c'];
alpha.concat(1, [2, 3]); //["a", "b", "c", 1, 2, 3]
alpha.concat(); // ['a', 'b', 'c']
4、push( element1,…,elementN ) 和 pop( )
push 添加一个或多个元素到数组的末尾,并返回数组新的长度;pop删除一个数组中的最后的一个元素,并且返回这个元素。
var data = [1, 2, 3];
data.push(4, 5, 6); // 6 > 数组的长度 data > [1,2,3,4,5,6]
data.pop(); //6 > 出栈的元素 data > [1,2,3,4,5]
注意:push 和 pop 并不会改变原来的元素位置。
5、unshift( element1, …, elementN ) 和 shift( )
unshift 添加一个或多个元素到数组的开头,并返回数组新的长度;shift 删除一个数组中的第一个元素,并且返回这个元素。
var data = [1, 2, 3];
data.unshift(-1, -2, -3); // 6 > 新数组的长度 data > [-1,-2,-3,1,2,3]
data.shift(); // -1 > 被移除的元素 data > [-2,-3,1,2,3]
注意:unshift 和 shift 都会改变原来的元素位置。
如果把数组看成一个栈,push 和 pop 、unshift 和 shift 对数组的操作行为就符合 后进先出 (LIFO) 规律 ;如果把数组看成一个队列,push
和 shift
、unshift
和 pop
对数组的操作行为就符合 先进先出 (FIFO) 规律。
因此,可以使用数组来实现对应的数据结构:栈和队列。
6、slice( begin [, end] )
slice 方法从begin 的索引位置开始提取数组元素,到 end 位置结束,但不包括 end 位置的元素,如果 end 被省略,则默认提取到数组的结尾,如果结束位置小于起始位置,则返回空数组。
var data = [1, 2, 3];
data.slice(0); // [1,2,3] 提取的元素
data.slice(1, 2); // [2] 提取的元素
data.slice(2, 1); // []
如果参数中有一个负数,则用数组长度加上该数来确定相应的位置。例如,在一个包含 5 项的数组上调用 slice(-2, -1) 与调用 slice(3, 4) 得到的结果相同。
var t = [1, 2, 3, 4, 5];
t.slice(-2, -1); // [4]
t.slice(3, 4); // [4]
slice方法会返回一个新的数组,由于数组是引用类型, 通常会通过 arr.slice(0) 来实现数组的 浅拷贝,但这只对 数组元素是基本类型 的情况有效。
// 简单数组拷贝
var arr = [1, 2, 3, 4];
var cyarr = arr.slice(0); // 浅拷贝
arr.splice(3, 1); // 对原数组操作
console.log(arr, cyarr); //[1,2,3] , [1,2,3,4] > 拷贝成功
如果是对象数组,数组元素作为指针指向对象内存,slice(0) 仅仅是拷贝了一份指针作为副本,而副本中的指针,指向的还是原来的对象,因此,对一个数组中的对象做操作,另一个数组中的对象也会同步变化。
//对象数组拷贝
var list = [{name: 'zhangsan'}];
var cylist = list.slice(0); // 浅拷贝
list[0].name = 'lisi'; // 对原数组操作
console.log(list, cylist); // [{name:'lisi'}] , [{name:'lisi'}] -> 拷贝失败
要实现数组的深拷贝,需要通过 JSON
的序列化和反序列化来实现,即: JSON.parse( JSON.stringify(arr) )
//对象数组拷贝
var list = [{name: 'zhangsan'}];
var cylist = JSON.parse(JSON.stringify(list)); // 深拷贝
list[0].name = 'lisi'; // 对原数组操作
console.log(list, cylist); // [{name: 'lisi'}] , [{name: 'zhangsan'}] > 拷贝成功
7、splice( start, deleteCount[,value1,…,valueN] )
splice方法从一个数组中移除一个或多个元素,如果必要,在所移除元素的位置上插入新元素,返回所移除的元素。
data.splice(2, 1); // [3] > 被删除的元素 data > [1,2]
data.splice(2, 2, 4, 5); // [3] > 被删除的元素 data > [1,2,4,5]
data.splice(2, 2, 4, 5, 6); // [3] > 被删除的元素 data > [1,2,4,5,6]
延伸阅读
数组与链表的区别
1、在访问方式上:
- 数组可以随机访问其中的元素;
- 链表则必须是顺序访问,不能随机访问。
2、空间的使用上:
- 链表可以随意扩大;
- 数组则不能。
文章标题:数组是什么,发布者:Z, ZLW,转载请注明出处:https://worktile.com/kb/p/49191