稀疏数组
基本介绍

- 稀疏数组的列数固定为3列
- 稀疏数组的行数=有效数据个数+1
稀疏数组的意义:
- 原数组中存在大量的无效数据,占据了大量的存储空间,有效数据很少。
- 压缩存储可以节省存储空间,避免资源不必要的浪费,在数据序列化到磁盘时,压缩存储可以提高IO效率。
处理步骤:
- 记录原数组的行数,列数,有效数据(不为0的数)。
把有效数据的的行数,列数和值记录在一个小规模的数组中,从而缩小程序的规模。
实际应用
使用稀疏数组来保留图中的棋盘(二维数组)
- 将稀疏数组重新恢复为二维数组

代码:
package ch03_sparseArray;/*** 稀疏数组*/public class SparseArray {public static void main(String[] args) {/***使用二维数组,模拟棋盘数据*/int[][] array = new int[11][11];array[1][2] = 1;array[2][3] = 2;//打印棋盘,查看效果for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {System.out.print(array[i][j] + " ");}System.out.println();}/*** 使用稀疏数组来保存以上二维数组*///计算二维数组中有效数据(不为0)的个数。int sum = 0;for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {if (array[i][j] != 0) {sum++;}}}/*定义稀疏数组1.稀疏数组的列数固定为3列2.稀疏数组的行数=有效数据个数+1*/int[][] sparseArray = new int[sum + 1][3];//原数组行数sparseArray[0][0] = 11;//原数组列数sparseArray[0][1] = 11;//有效数据个数sparseArray[0][2] = sum;//将有效数据存放至稀疏数组中int count = 0;for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {if (array[i][j] != 0) {count++;sparseArray[count][0] = i;sparseArray[count][1] = j;sparseArray[count][2] = array[i][j];}}}//打印稀疏数组System.out.println("-----------------------------------");for (int[] row : sparseArray) {for (int val : row) {System.out.print(val + "\t");}System.out.println();}/*** 将稀疏数组重新恢复为二维数组*///创建二维数组int[][] oldArray = new int[sparseArray[0][0]][sparseArray[0][1]];//赋值for (int i = 1; i <= count; i++) {oldArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];}//打印二维数组System.out.println("-------------------------------");for (int[] row : oldArray) {for (int i : row) {System.out.print(i+"\t");}System.out.println();}}}
队列
基本介绍

- 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。
- 进行插入操作的一端叫做队尾(rear),进行删除操作的一端称为队头(front)。
- 队列中的元素只能 先进先出(FIFIO)。
- 队列是一个有序列表,可以用数组和链表来实现。
循环队列

循环队列的出现就是为了解决队列的假溢出问题。
真溢出:我们运用数组实现队列时,数组长度为 5,我们放入了[1,2,3,4,5],此时如果继续加入 6 时,是真的满了,放不了。
假溢出:我们运用数组实现队列时,数组长度为 5,我们放入了[1,2,3,4,5],我们将 1,2 出队,此时如果继续加入 6 时,因为数组末尾元素已经被占用,再向后加则会溢出,但是我们的下标 0,和下标 1 还是空闲的。所以我们把这种现象叫做“假溢出”。
我们用来解决假溢出的方法就是后面满了,就再从头开始,也就是头尾相接的循环,我们把队列的这种头尾相接的顺序存储结构成为循环队列。
队尾指针指向的位置永远空出1位, 所以队列最大容量比数组长度小1。基本操作
我们发现队列为空时 front == rear,队列满时也是 front == rear,如何区分队列是空还是满?
- 设置标记变量 flag。
- 当队列为空时,front==rear;
当队列满时,我们保留一个元素空间,也就是说,队列满时,数组内还有一个空间

- 公式(判断队列是否满了):(rear+1)%queuesize==front
- rear:尾部指针指向的数组下标
- front:头部指针指向的数组下标
- queuesize:队列的长度
代码:
package ch04_queue;public class ArrayQueue {public static void main(String[] args) throws Exception {ArrayQueue arrayQueue = new ArrayQueue(5);arrayQueue.addQueue(1);arrayQueue.addQueue(2);arrayQueue.addQueue(3);arrayQueue.addQueue(4);arrayQueue.getQueue();arrayQueue.getQueue();arrayQueue.headQueue();//arrayQueue.output();}private int[] array;private int front;private int rear;public ArrayQueue(int capacity) {this.array = new int[capacity];}/*** 判断队列是否已满** @return:true-满了,false-没满*/public boolean isFull() {return (rear + 1) % array.length == front;}/*** 判断队列是否为空** @return:true-空,false-非空*/public boolean isEmpty() {return front == rear;}/*** 入队操作** @param element:入队元素*/public void addQueue(int element) throws Exception {if (isFull()) {throw new Exception("队列已满!");}array[rear] = element;rear = (rear + 1) % array.length;}/*** 出队操作** @return*/public int getQueue() throws Exception {if (isEmpty()) {throw new Exception("队列已空!");}int getElement = array[front];front = (front + 1) % array.length;return getElement;}/*** 输出队列*/public void output() {for (int i = front; i != rear; i = (i + 1) % array.length) {System.out.println(array[i]);}}/*** 输出队列的第一个数据*/public void headQueue(){System.out.println(array[front]);}}
递归
基本介绍
概念:
递归就是方法自己调用自己,每次调用时传入的参数是不同的,递归有助于解决程序中复杂的问题,同时可以让代码更为简洁。
规则:

