ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

数据结构与算法-数组

2021-01-29 12:05:08  阅读:182  来源: 互联网

标签:loc int 元素 算法 arraySize 数组 数据结构 data


 思考这样一道题目:

给你一个文件(近6G的文件)里面包含了全国人民(大约14亿)的年龄数据(大约是0~180左右),现在需要统计每个年龄段有多少人?

单机+2cpu+2G内存 以上情况你如何以最高效的的方法来解决这个问题?

用数组来解决: int[0] 这个下标0表示年龄 int[0] 的值是表示0岁的有多少人

  String str = null;
       String fileName = "D:\\age.txt";   //这个就是全部年龄数据文件
       InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName),"UTF-8");

       long start = System.currentTimeMillis();
       BufferedReader br = new BufferedReader(isr);
       int tot = 0 ;
       int data [] = new int[200];
       while((str = br.readLine()) != null){ //一行一行的读 O(n)
           int age = Integer.valueOf(str);
           data[age] ++ ;
           tot ++ ;
      }
       System.out.println("总共的数据大小: " + tot);   //总共的数据大小: 1400000000

       for(int i = 0 ; i < 200 ; i ++){//下标从0开始的
           System.out.println(i + ":" + data[i]);
      }
       System.out.println("计算花费的时间为:" + (System.currentTimeMillis() - start) + "ms"); //计算花费的时间为:89170ms

 

1、数组的定义

  数组是指有序的元素序列。如果将有限个类型相同的变量的集合命名,那么这个名称就是数组名,而组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组各个元素的数字编号称为下标。数组在程序设计中,为了处理方便,把具有相同类型的的若干元素组织起来的一种形式,这些无序排列的同类数据元素的集合称为数组。

2、数组的特点

  1、数组是相同数据类型的元素集合。

  2、数组当中的各个元素存储是有先后顺序的,他们在内存中按照这个先后顺序连续的存放在一起。

  3、数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。

3、表现形式

  1、一维数组

    int a[], String a[]

  2、多维数组

    Int a,int a[]

4、随机访问

  数组是连续的内存空间和相同类型的数据。正是因为这两个限制,它才有了一个非常重要的特性:随机访问,也就是查询是非常快速的且高效的,但有利就有弊,这两个限制也让数组的很多操作变得非常低效,比如要想在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。

 

这是简单的数组增删元素的内存示意图

 

 

 

这个是数组操作的简单代码实现 其实也是我们常用的ArrayList代码的简单实现,当然JDK封装的ArrayList的实现更复杂,涉及到扩容什么的。

public class ArrayTest {

   private int arraySize;  //数组长度
   private int data[];
   private int index;      //当前已经存的数大小

   /**
    * 构造函数初始化
    * @param arraySize
    */
   public ArrayTest(int arraySize){
       this.arraySize = arraySize;
       data = new int[arraySize];
       this.index = 0;
  }

   /**
    * 简单打印
    */
   public void print(){
       System.out.println("index:"+index);
       for (int i = 0; i <index ; i++) {
           System.out.println(data[i]+" ");
      }
       System.out.println();
  }

   /**
    * 数组添加元素
    * @param loc
    * @param n
    */
   public void add(int loc,int n){     //时间复杂度   分析极端情况 从第一个元素插入 时间复杂度就是O(n) 最后一个元素插入时间复杂度就是O(1)
       if(index++ < arraySize){
           for (int i = arraySize-1; i > loc ; i--) {
               data[i] = data[i-1];
          }
           data[loc] = n;
      }
  }

   /**
    * 数组删除元素
    * @param loc
    */
   public void delete(int loc){ //时间复杂度   分析极端情况 从第一个元素删除 时间复杂度就是O(n) 最后一个元素删除时间复杂度就是O(1)
       for (int i = loc; i < arraySize ; i++) {
           if(i!= arraySize-1){   //
               data[i] = data[i+1];
          }else{
               data[i] = 0;
          }
      }
       index--;
  }

   /**
    * 数组更新元素
    * @param loc
    * @param n
    */
   public void update(int loc,int n){ //时间复杂度 O(1)
       data[loc] = n;
  }

   /**
    * 数组的查询
    * @param loc
    * @return
    */
   public int get(int loc){ //时间复杂度 O(1)
       return data[loc];
  }

}

ArrayList和数组:

  其实他们本质是一样的,都是数组。

  ArrayList是JDK封装的 提供了操作数组的api,包括扩容操作也实现了。

  数组操作的话需要自己全部实现。

ArrayList和数组选择:

  不知道数组大小的情况下选择ArrayList

  如果知道大小且对性能要求很高的话,选择数组。

 

数组最需要注意的就是数组越界 ArrayIndexOutOfBoundsException

 

 

为什么很多计算机编程语言中的数组下标是从0开始的?

  当我们定义数组的时候,根据数组的特点(连续的)在内存分配空间的时候,分配是一段连续的内存空间

  如 int a = new int[3]

  假如申请的内控地址是 10001 10002 10003

  int[0] ==> 10001 ==> 10001+0*typesize

  int[1] ==> 10002 ==> 10001+1*typesize

  int[2] ==> 10003 ==> 10001+2*typesize

  后面的 0 1 2就是对应前面数组的下标

 

  假如我们不是从0开始 而是1开始

  int[1] ==> 10001 ==> 10001+(1-1)*typesize

  int[2] ==> 10002 ==> 10001+(2-1)*typesize

  int[3] ==> 10003 ==> 10001+(3-1)*typesize

  这样就多了一步的底层运算 而且了解计算机底层计算的话,减法运算其实就是加一个负数 ,其中会涉及到反码补码等操作。

 

 

 

 

 

标签:loc,int,元素,算法,arraySize,数组,数据结构,data
来源: https://www.cnblogs.com/henrychenhao/p/14344152.html

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

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

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

ICode9版权所有