ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构之数组详解

2020-06-02 23:00:35  阅读:633  来源: 互联网

标签:arrClone arrInt int System 详解 数组 new 数据结构


数组(Array)是由相同类型的元素(element)集合组成的固定长度(Size)的一种数据结构。在内存中是连续存储的,因此可以通过索引(Index)计算出某个元素的地址。 下面介绍都是已java为示例。对于没有详细了解过的  相信有所收获。  

基础知识

声明

type arrayName[] 或者 type[] arrayName。 如:
int arrInt[] 或者 int[] arrInt
声明过程,只是告诉编译器: arrInt变量保存了一个int类型的数组。这个过程并没有分配内存。

new分配内存

分配内存需要通过new完成,同时指明类型和数组大小。 如:
int[] arrInt = new int[4];
数组中元素通过new分配后自动完成初始化,一般有几种:数字类型初始化为0(如:int/byte/short/long初始化为0,float/double初始化为0.0),布尔型初始化为false(boolean初始化为false),String或者其他对象类型初始化为null。 数组赋值也有两种
int[] arrInt = {1,3,5,7};
或
int[] arrInt = new int[4];
arrInt[0] = 1;
arrInt[1] = 3;
arrInt[2] = 5;
arrInt[3] = 7;

 示意图如下:

多维数组

多维数组类似,即数组中的元素也是数组。如
int[][] arrInt = {{1,3,5},{2,4,6},{0,10,20}};

示意图如下:

     

数组特点

 

  1. 索引(即下标) 一般从0开始,如java, C/C++。
  2. 长度固定,在申请时长度固定。内存连续,在内存中则是申请一块连续的固定大小的空间。
  3. 数组有一维数组和多维数组,数组元素可以是基本数据类型(Primitive),也可以是对象引用(Reference)。
  4. 随机访问,能够根据位置(下标)直接访问到元素。

 

注: 基本数据类型和对象引用数据类型 Primitive类型在java中有八种(具体内容后续整理),Primitive类型在内存位置直接存入实际的值,引用对象的内存分配是在堆上(Heap)。 Primitive类型: boolean、char、byte、short、int、long、float、double 数组下标从0开始 数组变量引用 指向了数组实际分配的连续内存的开始地址 即第一个元素的地址(firstAdrr)数组下标(index)即偏移量。假使每个元素大小为size. 那么数组元素位置计算:firstAdrr+index*size。 所以大部分语言数组下标是0开始。如果从1开始,计算位置时偏移量要减1操作,多了一步运算。  

数组关联的Class对象

每个数组有一个关联的Class对象,与其他相同类型数组共享。 如:JNI中传递的参数经常看到:I表示int类型,[ 表示一个数组,[I 即int数组。
System.out.println("int array:" + new int[3].getClass());
System.out.println("int array:" + new int[3].getClass().getSuperclass());
System.out.println("String array:" + new String[3].getClass());
System.out.println("boolean array:" + new boolean[3].getClass());
结果为:
int array:class [I
int array super:class java.lang.Object
String array:class [Ljava.lang.String;
boolean array:class [Z

 

数组的拷贝

一维数组拷贝

一维数组的clone()是 深度拷贝,拷贝了数组内的原始数据到新数组,而不是引用的复制。  如:
int arrInt[] = {1,2,3};
 
int arrClone[] = arrInt.clone();
arrClone[1] = 5;
  
System.out.println(arrInt == arrClone);
  
for (int i = 0; i < arrClone.length; i++) {
    System.out.println(arrInt[i]+" "+arrClone[i]);
}
结果为:
false
1 1
2 5
3 3

示意图如下: 

多维数组拷贝

但多维数组则不是这样。如:
int arrInt[][] = {{1,2,3},{4,5,6}};
        
int[][] arrClone = arrInt.clone();
arrClone[0][1] = 50;
arrInt[0][1] = 100;
  
System.out.println(arrInt == arrClone);
System.out.println(arrInt[0] == arrClone[0]);
  
for (int i = 0; i < arrInt.length; i++) {
    for (int j = 0; j < arrInt[i].length; j++) {
        System.out.println(arrInt[i][j]+" "+arrClone[i][j]);
    }
    
}
结果为:
false
true
1 1
100 100
3 3
4 4
5 5
6 6

 示意图如下:

     

数组操作

插入

如图,向数组中插入一个元素,插入位置及之后的所有元素都需要向后挪动一位来完成插入操作。 如果数组已经满了(或者保证数组长度与元素个数一致),则只能创建一个新的数组(长度增加的)来完成插入操作。 时间复杂度上,最好的是数组未满插入到最后 只需直接插入,操作一次(O(1))。最坏是插入到第一位,需要操作N次。 平均时间复杂度,(1 + 2 + ... + n) / n ~= O(n)   这是一个简单的插入示例。在现有数组的position位置插入value值,首先创建了一个新数组(长度+1),依次填入数据。
private int[] insertArr(int[] srcArr, int position, int value) {
    if (position < 0 || position >= srcArr.length) return null;
    int[] desArr = new int[srcArr.length+1];
    System.arraycopy(srcArr, 0, desArr, 0, position);
    desArr[position] = value;
    System.arraycopy(srcArr, position, desArr, position+1, srcArr.length-position);
    return desArr;
}

 

删除

类似插入的反向操作,删除某个元素,该位置及之后的所有元素 向前挪一位。 如果要保证数组长度与数组元素个数一致,则也需要重新创建一个(长度减小的)数组来完成。 示意图:  

查找

查找某一元素位置,只能一位位的遍历查找了。  

访问

对于某位置的元素,直接读取或修改 就可以了。数组是随机访问的。  

时间复杂度总结

最后整理个表格,上述操作的时间复杂度大致如下,很容易理解就不详细解释了。

操作 平均时间复杂度 最坏条件时间复杂度
插入 O(n) O(n)
删除 O(n) O(n)
查找 O(n) O(n)
访问 O(1) O(1)
   

标签:arrClone,arrInt,int,System,详解,数组,new,数据结构
来源: https://www.cnblogs.com/fanglongxiang/p/13034353.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有