1、线性表之数组-简介
1、数组-概述: 1-1、数组是一种连续存储线性结构[在内存中连续存储多个元素的结构,在内存中的分配也是连续的],元素类型相同,大小相等。 1-2、数组可以是多维的,通过使用整型索引值来访问他们的元素,用来存储固定大小元素的线性表。 1-3、对于指定下标的查找,时间复杂度为O(1);对于一般的插入删除操作, 涉及到数组元素的移动,其平均复杂度也为O(n)。2、数组-优点 2-1、按照索引查询元素速度快 2-2、按照索引遍历数组方便3、数组-缺点: 3-1、数组的大小固定后就无法扩容了 3-2、数组只能存储一种类型的数据 3-3、添加,删除的操作慢,因为要移动其他的元素(如果是添加删除末尾的话,那速度不慢)4、数组-适用场景: 4-1、频繁查询,对存储空间要求不大,很少增加和删除的情况。5、数组的常见应用: 5-1、ArrayList、LinkedList、Vector、6、普通数据-举例Demo: public static void main(String[] args) { Integer[] integers = new Integer[10]; integers[0]=0;//王五 integers[1]=1; integers[2]=2; }
2.1、稀疏数组(SparseArray)
1、稀疏数组(SparseArray)-介绍: 1-1、当一个数组中大部分元素为0,或元素值为同一个时,可使用稀疏数组来保存该数组 1-2、处理方式: 1-2-1、记录数组一共有几行几列、有多少个不同的值。 1-2-2、把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。 1-3、代码示例 第一行存储原始数据总行数,总列数,总的非0数据个数 接下来每一行都存储非0数 所在行,所在列,和具体值 rows cols n r1 c1 val1 r2 c2 val2 . . . . . . rn cn valn
2.2、普通数组与稀疏数组互转
public class SparseArray { /** * 稀疏数组可以简单的看作为是压缩,在开发中也会使用到。比如将数据序列化到磁盘上,减少数据量,在IO过程中提高效率等等。 * @param args */ public static void main(String[] args) throws Exception { /** * 初始化二维数组 * <p> * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 1 0 0 0 0 0 0 0 0 * 0 0 0 0 2 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * </p> */ //初始化原数组,[row][col] int[][] originalArray = new int[11][11]; originalArray[1][2] = 1; originalArray[2][4] = 2; for(int[] row : originalArray){ for(int item : row){ System.out.printf("%d\t",item); } System.out.println(); } System.out.println("---------> 二维数组转稀疏数组"); /** * 稀疏数组 * <p> * 11 11 2 * 1 2 1 * 2 4 2 * </p> */ //得到非0数据数 int sum = 0; for (int i = 0;i<originalArray.length;i++){ for(int j = 0;j<originalArray[i].length;j++){ if(originalArray[i][j] != 0){ sum++; } } } //创建稀疏数组 int[][] sparseArray = new int[sum+1][3]; //给稀疏数组赋值 sparseArray[0][0] = 11; sparseArray[0][1] = 11; sparseArray[0][2] = sum; //将非0的数放入稀疏数组 //count:标识第几个非0数 int count = 0; for (int i = 0;i<11;i++){ for(int j = 0;j<11;j++){ if(originalArray[i][j] != 0){ count++; sparseArray[count][0] = i; sparseArray[count][1] = j; sparseArray[count][2] = originalArray[i][j]; } } } //遍历稀疏数组 for(int i = 0;i<sparseArray.length;i++){ System.out.printf("%d\t%d\t%d\t\n",sparseArray[i][0],sparseArray[i][1],sparseArray[i][2]); } System.out.println("----------->稀疏数组转回原始数组"); // 将稀疏数组存入磁盘(文件) sparseArrayToIo(sparseArray); //将稀疏数组 恢复成原始的二维数组 //先读取稀疏数组的第一行 根据第一行创建原始的二维数组 比如上面的chessArr2=int[11][11] //读取稀疏数组后 几行的数据 并赋给原始的二维数组 int newArray[][]=new int[sparseArray[0][0]][sparseArray[0][1]]; for(int i=1;i<=count;i++){ newArray[sparseArray[i][0]][sparseArray[i][1]]=sparseArray[i][2]; } System.out.println("打印读取出来的二维数组"); for(int i=0;i<newArray.length;i++) { for (int j = 0; j < newArray[i].length; j++) { System.out.printf("%d\t", newArray[i][j]); } System.out.println(); } } /** * 将稀疏数组存入磁盘(文件) * */ public static void sparseArrayToIo(int[][] sparseArray) throws Exception { OutputStreamWriter ow = null; String filePath = "D:\\IdeaSelfLearnSpace\\DataStructureStudy\\sparseArray.txt"; File file = new File(filePath); try { if(!file.exists()){ file.createNewFile(); } ow = new OutputStreamWriter(new FileOutputStream(filePath),"UTF-8"); //设置文件内容往后追加,默认为false //bw = new BufferedWriter(new FileWriter(file, true)); //写入 for(int i =0; i < sparseArray.length; i++) { for(int j = 0; j < sparseArray[i].length; j++) { ow.write(sparseArray[i][j]+" "); } } } catch (IOException e) { e.printStackTrace(); } finally { //关闭流 try { if(ow != null){ ow.flush(); ow.close(); } } catch (IOException e) { e.printStackTrace(); } } }}
2.3、数组-相关问题-列举
1、为什么大多数编程语言中,数组要从0开始编号,而不是1开始呢? 1-1、答:-- 下标即为 偏移量(offset), 假设a代表数组首地址,a[0]=偏移量为0的位置,即首地址,那么a[k]=偏移量k个type_size的位置, a[k]地址公式为:a[k]_address = base_address + k * type_size 假设数组从 1 开始计数,那我们计算数组元素,a[k] 的内存地址就会变为:a[k]_address = base_address + (k-1)*type_size 1-2、问题总结:从 1 开始编号,每次随机访问数组元素都多了一次减法运算,对CPU来说就是多了一次减法指令。