目录
一、数据结构和算法的关系
二、数据结构的分类
(一)线性结构
(二)非线性结构
三、稀疏数组(sparsearray)
(一)稀疏数组的基本介绍
(二)稀疏数组的处理方法
一、数据结构和算法的关系
数据data结构(structure)是一门研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构可以编写出更加漂亮,更加有效率的代码。要学习好数据结构就要多多考虑如何将生活中遇到的问题,用程序去实现解决。程序 = 数据结构 + 算法。数据结构是算法的基础,换言之,想要学好算法,需要把数据结构学到位。
二、数据结构的分类
(一)线性结构
- 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。
- 线性结构有两种不同的存储结构,即顺序存储结构和链式存储结构。顺序存储的线性表称为顺序表,顺序表中的存储元素(地址)是连续的。
- 链式存储的线性表称为链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息。
- 线性结构常见的有:数组、队列、链表和栈。
(二)非线性结构
非线性结构包括:二维数组,多维数组,广义表,树结构,图结构。
三、稀疏数组(sparsearray)
(一)稀疏数组的基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
(二)稀疏数组的处理方法
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
二维数组转稀疏数组的思路:
1.遍历原始的二维数组,得到有效数据的个数sum
2.根据sum就可以创建稀疏数组sparseArr int[sum+1][3]
3.将二维数组的有效数据存入到稀疏数组中
4.将稀疏数组保存到磁盘中
稀疏数组转原始的二维数组的思路
1.磁盘文件先恢复为稀疏数组
2.读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的chessArr2=int[11][11]
3.再读取稀疏数组后几行的数据,并赋给原始的二维数组即可。
代码实现:
package com.atguigu.practices.sparsearray;
import java.io.*;
public class SparseArray2 {
public static void main(String[] args){
// 创建棋盘11*11,棋盘也可能不规则
int chessArr[][] = new int[11][11];
// 设定棋子:0是没有棋子;1是黑子;2是白子
// 棋盘初始化
chessArr[1][5]=1;
chessArr[2][3]=2;
// 遍历这个初始棋盘
for (int[] row :
chessArr) {
for (int data:
row) {
System.out.print(data+"\t");
}
System.out.println();
}
// 将棋盘转为稀疏数组
// 稀疏数组总是3列,稀疏数组的行是棋子的坐标,且非0的才会显示在稀疏数组中
// 遍历棋盘,找出非0的棋子数
int sum = 0;
for (int i = 0; i < chessArr.length; i++) {
for (int j = 0; j < chessArr[i].length; j++) {
if(chessArr[i][j]!=0){
sum++;
}
}
}
System.out.println("棋盘中一个有"+sum+"个棋子");
// 创建稀疏数组
int sparseArr[][] = new int[sum+1][3];
// 稀疏数组初始化
sparseArr[0][0]=chessArr.length;
sparseArr[0][1]= chessArr[0].length;
sparseArr[0][2]=sum;
// 给稀疏数组赋值
int count = 0;
for (int i = 0; i < chessArr.length; i++) {
for (int j = 0; j < chessArr[i].length; j++) {
if(chessArr[i][j]!=0){
count++;
sparseArr[count][0]=i;
sparseArr[count][1]=j;
sparseArr[count][2]=chessArr[i][j];
}
}
}
// 遍历稀疏数组
System.out.println("稀疏数组为:");
for (int i = 0; i < sparseArr.length; i++) {
System.out.println(sparseArr[i][0]+"\t"+sparseArr[i][1]+"\t"+sparseArr[i][2]);
}
// 稀疏数组转二维数组
// 稀疏数组的第一行的前两个数据就是二维数组的行列
int newChessArr[][] = new int[sparseArr[0][0]][sparseArr[0][1]];
// 从稀疏数组的第二行开始给新的二维数组赋值
for (int i = 1; i < sparseArr.length; i++) {
newChessArr[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
}
// 遍历二维数组
System.out.println("新的二维数组是:");
for (int i = 0; i < newChessArr.length; i++) {
for (int j = 0; j<newChessArr[i].length;j++){
System.out.print(newChessArr[i][j]+"\t");
}
System.out.println();
}
System.out.println("----------------------------------------------");
System.out.println("稀疏数组的读写------------------------------------");
// 将稀疏数组存储到磁盘中
// 边写边读
FileOutputStream fos = null;
OutputStreamWriter osw = null;
FileInputStream fis = null;
InputStreamReader isr = null;
try {
fos = new FileOutputStream("./resources/map.data");
osw = new OutputStreamWriter(fos, "UTF8");
System.out.println("写入中..............");
// 遍历稀疏数组
for (int i = 0; i < sparseArr.length; i++) {
osw.write(sparseArr[i][0]+"\t"+sparseArr[i][1]+"\t"+sparseArr[i][2]+"\t");
}
osw.close();
fos.close();
System.out.println("写入磁盘成功");
System.out.println("读取中.................");
fis =new FileInputStream("./resources/map.data");
isr =new InputStreamReader(fis,"UTF8");
StringBuffer sb = new StringBuffer();
while (isr.ready()){
sb.append((char) isr.read());
}
isr.close();
fis.close();
System.out.println("读取成功!");
// String ss = sb.toString();
String[] sb1 = sb.toString().split("\t");
// 遍历读取出来的文件
System.out.println("遍历读取出来的文件");
for (int i = 0; i < sb1.length; i++) {
System.out.print(sb1[i]+"\t");
}
System.out.println("字符串的长度为:"+sb1.length);
// 读取出来的结果是字符串,要想转回为稀疏数组,就要把字符串转为数值
// 重新定义一个稀疏数组
int newSpareArr[][] = new int[sb1.length/3][3];
// 稀疏数组第一行初始化
newSpareArr[0][0]=Integer.parseInt(sb1[0]);
newSpareArr[0][1]=Integer.parseInt(sb1[1]);
newSpareArr[0][2]=Integer.parseInt(sb1[2]);
// 从第四个值开始,给稀疏数组赋值
int data = 0;
for (int i = 3; i < sb1.length; i+=3) {
data++;
newSpareArr[data][0]=Integer.parseInt(sb1[i]);
newSpareArr[data][1]=Integer.parseInt(sb1[i+1]);
newSpareArr[data][2]=Integer.parseInt(sb1[i+2]);
}
// 遍历读出来的稀疏数组
System.out.println("恢复后的稀疏数组...............");
for (int i = 0; i < newSpareArr.length; i++) {
System.out.println(newSpareArr[i][0]+"\t"+newSpareArr[i][1]+"\t"+newSpareArr[0][2]);
}
// 将恢复后的稀疏数组转换为二维数组
// 定义一个新的二维数组
int chessNew[][] = new int[newSpareArr[0][0]][newSpareArr[0][1]];
// 稀疏数组从第二行开始给新的二维数组赋值
for (int i = 1; i < newSpareArr.length; i++) {
chessNew[newSpareArr[i][0]][newSpareArr[i][1]]=newSpareArr[i][2];
}
// 遍历新的二维数组
System.out.println("稀疏数组转二维数组................");
for (int i = 0; i < chessNew.length; i++) {
for (int j = 0; j < chessNew[i].length; j++) {
System.out.print(chessNew[i][j]+"\t");
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}