数据结构与算法
数据结构
线性结构
概述
特点:数据元素之间存在一对一的线性关系。
存储结构:顺序存储结构和链式存储结构。
- 顺序存储结构:顺序存储的线性表称为顺序表,顺序表中存储的元素是连续的。
- 链式存储结构:链式存储的线性表称为链表,链表中存储的元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息。
常见的线性结构
数组、队列、链表、栈。
非线性结构
常见的非线性结构
二维数组、多为数组、广义表、树结构、图结构。
稀疏数组
应用场景
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是
1)记录数组一共有几行几列,有多少个不同的值
2)把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模

二维数组和稀疏数组的互相转换
思路
二维数组转稀疏数组的思路
- 遍历原始的二维数组,得到有效数据的个数sum。
- 根据sum就可以创建稀硫数组 sparseArr int【sum+1】【3】。
- 将二维数组的有效数据数据存入到稀硫数组。
稀硫数组转原始的二维数组的思路
- 先读取稀硫数组的第一行,根据第一行的数据,创建原始的二数组,比如上面的 chessEr2=nt
- 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可.
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| package DataStructures.SparseArray;
public class SparseArray {
private static int[][] sparseToArray(int[][] sparseArray) { int[][] result = new int[sparseArray[0][0]][sparseArray[0][1]]; for (int i = 1; i < sparseArray.length; i++) { result[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2]; } return result; }
private static int[][] toSparseArray(int[][] arr) { int sum = 0; for (int[] ints : arr) { for (int anInt : ints) { if (anInt != 0){ sum++; } } } int[][] sparseArray = new int[sum + 1][3]; sparseArray[0][0]=arr.length; sparseArray[0][1]=arr[0].length; sparseArray[0][2]=sum; int count = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { if(arr[i][j] != 0){ count++; sparseArray[count][0] = i; sparseArray[count][1] = j; sparseArray[count][2] = arr[i][j]; } } } return sparseArray; } }
|

队列
队列介绍
队列是一个有序列表,可以用数组或是链表来实现。
遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后
出
示意图:(使用数组模拟队列示意图)

数组模拟队列
录队列前后端的下标, front会随看数据输出而改变r,而rear则是随着数据输入而改变。

思路
当我们将数据存入队列时称为” addQueue“, addQueue的处理需要有两个步
骤:
将尾指针往后移:rea+1,当 front=rear【空】
若尾指针rear小于队列的最大下标 maxSize-1,则将数据存入rear所指的数
组元素中,否则无法存入数据。rear== maxSize-1【队列满】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| class ArrayQueue { private int maxSize; private int front; private int rear; private int[] arr;
public ArrayQueue(int size) { this.maxSize = size; this.arr = new int[maxSize]; this.front = -1; this.rear = -1; }
public boolean isEmpty() { return front == rear; }
public boolean isFull() { return rear == maxSize -1; }
public void addQueue(int n){ if(isFull()){ throw new RuntimeException("队列满!"); }else { arr[++rear] = n; } }
public int getQueue(){ if(isEmpty()){ throw new RuntimeException("队列空!"); }else { return arr[++front]; } }
public int[] showQueue() { if (isEmpty()){ throw new RuntimeException("队列空!"); }else { return arr; } }
public int peek(){ if(isEmpty()){ throw new RuntimeException("队列空!"); }else { return arr[++front]; } } }
|
缺点:数组只能使用一次,没法复用。
优化:改进成环形队列,取模:%。
数组模拟环形队列思路
参数调整
- front:指向队列的首元素。初始值为0
- rear:指向队列的最后一个元素。空出一个空间做约定。初始值为0;
- 队满:(rear+1)%maxSize == front
- 队空: rear==front
- 队列中有效数据为 (rear+maxSize-front)%maxSize
代码实现