数据结构算法爬坑日记一
2020-08-16 16:02
543 查看
稀疏数组、队列
数据结构分类
线性结构:最常用的数据结构,特点是数据元素之间存在一对一的线性关系 ** 分俩种存储结构 ** 1.顺序存储结构:又称为顺序表,存储元素是连续的 ** 2.链式存储结构:又称为链表,存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址结构 常见线性数据结构:数组、队列、链表、栈 非线性结构:常见二维数组、多维数组、广义表、树、图
稀疏数组(SparseArray)
使用场景:如果一个数组很多元素的值都相同时,使用稀疏数组来保存该数组,缩小存储规模,提高效率 以二维数组转化的稀疏数组为例:第一行为二维数组的总行数、总列数和不为0的数,第二行开始记录每个不为0的 数的具体位置,第一列为行的位置,第二列为列的位置,第三列为具体的值 示例: 需求:五子棋盘映射为一个二维数组,将此二维数组保存到一个稀疏数组内,存入磁盘并读取再转化为二维数组 ** 代码实现 public class SparseTest { public static void main(String[] args) throws IOException, ClassNotFoundException { //要求:定义一个6*8二维数组,随意存入俩个数据,将此二维数组转换为稀疏数组写入磁盘,读取文件将稀疏数组转换为二维数组 //1.定义初始二维数组 int [][] arr=new int[6][8]; arr[1][2]=1; arr[2][3]=2; //2.遍历二维数组获得不为0的项的个数 int sum=0; for (int[] i : arr) { for (int j : i) { if (j != 0) { sum++; } } } //定义对应稀疏数组,将二维数组不为0的数据存入 int [][] sparseArr=new int[sum+1][3]; sparseArr[0][0]=arr.length; sparseArr[0][1]=arr[0].length; sparseArr[0][2]=sum; int count=0; // 记录第i个非0数 for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { if(arr[i][j]!=0){ count++; sparseArr[count][0]=i; sparseArr[count][1]=j; sparseArr[count][2]=arr[i][j]; } } } //将稀疏数组写入磁盘,采用对象序列化的方式 File file=new File("D:\\1.txt"); ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(file)); out.writeObject(sparseArr); out.close(); //从磁盘将稀疏数组反序列化 ObjectInputStream in=new ObjectInputStream(new FileInputStream(file)); int [][] newSparseArr = (int[][]) in.readObject(); //将新的稀疏数组转化为二维数组并验证结果 int [][] newArr=new int[newSparseArr[0][0]][newSparseArr[0][1]]; for (int i = 1; i < sparseArr.length; i++) { newArr[newSparseArr[i][0]][newSparseArr[i][1]]=newSparseArr[i][2]; } System.out.println(Arrays.deepToString(newArr)); } }
队列(Queue)
一种有序列表,可以用数组和链表来实现,特点:先存入的先取出,后存入的后取出 ** 示例(数组模拟环形队列) package myQueue; //数组模拟环形队列 @SuppressWarnings("all") public class RoundQueue { private int maxSize; // 队列长度为max-1 private int front; // 指向队列头部 private int rear; // 指向队列尾部得后一个位置 private int[] arr; // 容器 //初始化队列 public RoundQueue(int max){ maxSize=max; front=0; rear=0; arr=new int[maxSize]; } //判断队列是否已满 public boolean isFull(){ return (rear+1)%maxSize==front; } //判断队列是否为空 public boolean isEmpty(){ return rear==front; } //向队列添加数据 public void addRoundQueue(int data){ if(isFull()){ System.out.println("队列已满,无法添加"); return; } arr[rear]=data; rear=(rear+1)%maxSize; System.out.println("添加了 "+data); } //从队列取出数据 public void getRoundQueue(){ if(isEmpty()){ throw new RuntimeException("队列已空,无法取出"); } int data=arr[front]; front=(front+1)%maxSize; System.out.println("取出得数据为 "+data); } //显示队列全部数据 public void showRoundQueue(){ if(isEmpty()){ throw new RuntimeException("队列已空,无法查看"); } //循环展示队列数据,从头位置循环到尾部位置 // 因为是环形队列,所以获取下标时需要通过取模进行限制,底层是数组,防止下标越界 // 并且在尾部后一个位置已经到队列尾部的时候,如果数组前面有位置可以存,取模可以将空位移到 //开始位置 for (int i = front; i <front+(rear-front+maxSize)%maxSize ; i++) { System.out.println("队列内数据 "+arr[i%maxSize]); } } //显示队列头部数据 public void peep(){ if(isEmpty()){ throw new RuntimeException("队列已空,无法查看头数据"); } System.out.println(arr[front]); } } ** 测试 public class QueueTest { public static void main(String[] args) { ArrayQueue arrayQueue = new ArrayQueue(3); boolean flag=true; while (flag){ System.out.println("s 查看队列数据"); System.out.println("h 查看队列头数据"); System.out.println("a 向队列添加数据"); System.out.println("g 取出队列数据"); System.out.println("e 退出队列"); Scanner scanner = new Scanner(System.in); switch (scanner.next()){ case "s": try{ arrayQueue.showQueue(); }catch (Exception e){ System.out.println(e.getMessage()); } break; case "h": try { arrayQueue.peep(); }catch (Exception e){ System.out.println(e.getMessage()); } break; case "a": System.out.println("请输入添加数据"); arrayQueue.addQueue(scanner.nextInt()); break; case "g": try { arrayQueue.getQueue(); }catch (Exception e){ System.out.println(e.getMessage()); } break; case "e": flag=false; break; default:break; } } } } ** 无法循环重复利用的队列实现(测试同上) package myQueue; //数组模拟队列 public class ArrayQueue { private final int max; private int front; private int rear; private int[] arrQueue; //初始化队列对象 public ArrayQueue(int maxLength){ max=maxLength; front=-1;//指向队列头部前一个位置 rear=-1;//指向队列尾部的位置,包含尾部的那个数据 arrQueue=new int[maxLength]; } //判断队列是否为空 public boolean isEmpty(){ return rear==front; } //判断队列是否已满 public boolean isFull(){ return rear==max-1; } //向队列内添加数据 public void addQueue(int dada){ if(isFull()){ System.out.println("队列已满"); return; } rear++; arrQueue[rear]=dada; System.out.println("存入队列数据为 "+dada); } //从队列内取出数据 public void getQueue(){ if(isEmpty()){ throw new RuntimeException("队列为空"); } front++; System.out.println("取出的数据为 "+arrQueue[front]); } //查看队列全部数据 public void showQueue(){ if(isEmpty()){ throw new RuntimeException("队列为空"); } for (int i : arrQueue) { System.out.println("队列中的数据为 "+i); } } //查看队列头部数据 public void peep(){ if(isEmpty()){ throw new RuntimeException("队列为空"); } System.out.println("队列头数据为 "+arrQueue[front+1]); } }
相关文章推荐
- 【数据结构】第一讲 基本概念(数据结构&算法&复杂度)
- 数据结构简单入门/复习(七)-图的代码示例(C语言)
- HBase/TiDB都在用的数据结构:LSM Tree,不得了解一下?
- 【数据结构】:链表(Python实现)
- 图解九大常见数据结构,24张图彻底弄懂
- Leetcode刷题(22) 以基本数据结构的高级数据结构及其API
- MySQL优化必备之执行计划explain,索引基本知识,索引数据结构推演
- 数据结构与算法 ---- 图的广度优先搜索(BFS)和深度优先搜索(DFS)
- 图解 Java 中的数据结构及原理!
- 数据结构与算法 ---- 哈希表查找
- 8.1、STL总述、发展史、组成,数据结构谈
- Pandas库--数据结构
- 数据结构与算法 ---- 分块查找
- 数据结构与算法——图及图的搜索算法(C++)
- 数据结构简单入门/复习(六)-图的知识介绍(C语言)
- 数据结构简单入门/复习(五)-树与二叉树的代码示例(C语言)
- 数据结构简单入门/复习(四)-树与二叉树的知识介绍(C语言)
- 数据结构简单入门/复习(三)-栈与队列(C语言)
- 数据结构简单入门/复习(二)-循环链表与双向链表(C语言)
- pandas学习笔记---1.2:pandas数据结构Series