p6、 线性结构与非线性结构
线性结构:
- 数据元素之间一对一
- 分类:顺序存储结构(地址连续,数组),链式存储结构(地址不连续,链表)
- 常见例子:数组,链表,栈,队列
非线性结构
p7-p9、 稀疏数组(Exercise未做)
应用场景:
数组中大部分元素为0,或数组中全部元素为同一个值
处理方法:
首先记录原数组信息(原数组大小,原数组中值的个数),然后用一个小规模数组存储要存储的信息(位置,值)
稀疏数组与二维数组互相转化:
1.二维数组==>稀疏数组:
- (1)用一个n行3列(row,column,value)的稀疏数组存储该二维数组的信息
- (2)稀疏数组第一行存储原始二维数组的整体信息(二维数组维度,二维数组非0值个数)
- (3)稀疏数组其余行存储原始二维数组非0值信息(位置,值)
2.稀疏数组==>二维数组:
- (1)根据稀疏数组第一行元素,构造同维度的二维数组
- (2)根据稀疏数组其余行元素,填值
p10队列
应用场景:
排队问题
队列介绍:
有序列表,可用数组或链表实现,先入先出
实现方式1:数组
思路:
定义maxSize为队列最大容量,front指向头(不包含,初始值-1),rear指向尾(包含,初始值-1),输入数据时rear变动,输出数据时,front变动
方法:
//初始化队列 public ArrayQueue(int maxSize) { this.maxSize = maxSize; arr = new int[maxSize]; front = -1; rear = -1; } //判断队列是否满 public static boolean isFull(ArrayQueue arrayQueue) { return arrayQueue.rear == arrayQueue.maxSize - 1;//rear == maxSize -1,队列已满 } //判断队列是否空 public static boolean isEmpty( ArrayQueue arrayQueue){ return arrayQueue.front == arrayQueue.rear;//front == rear,队列为空 } //添加数据到队列 public static void addQueue(ArrayQueue arrayQueue,int num){ //首先判断队列是否已满 if (!arrayQueue.isFull(arrayQueue)){ arrayQueue.rear++;//尾指针此时有值,先移动尾指针 arrayQueue.arr[arrayQueue.rear] =num; //合并写法:arr[++rear] =num; System.out.println("添加 " + num + "成功~~"); }else { System.out.println("队列满了捏~~~"); } } //从队列取数据 public static int getQueue(ArrayQueue arrayQueue){ //首先判断队列是否空 if (!arrayQueue.isEmpty(arrayQueue)){ arrayQueue.front++;//头指针此时无值,先移动头指针 return arrayQueue.arr[arrayQueue.front]; //合并写法:return arr[++front]; }else { throw new RuntimeException("队列为空捏~~~");//throw本身会导致代码中断 } } //显示队列所有数据 public static void showQueue(ArrayQueue arrayQueue){ if (0 == arrayQueue.rear - arrayQueue.front){ System.out.println("队列为空捏~~~"); return; }else { System.out.println("展示队列"); for(int i = (arrayQueue.front) + 1;i < arrayQueue.rear + 1;i ++){ System.out.println(arrayQueue.arr[i]); } } } //显示队列头数据,不是取出数据 public int headQueue(ArrayQueue arrayQueue){ if (!arrayQueue.isEmpty(arrayQueue)){ return arr[front + 1]; }else { throw new RuntimeException("队列为空捏~~"); } }
问题:
数组使用一次就不能使用,没有达到复用效果 ===>循环队列解决
实现方式1.1:数组实现循环队列
思路:
调整front定义为:指向队列第一个元素,初始值为0
调整rear定义为:指向队列最后一个元素的后一个位置(空出一个空间作为约定),初始值为0
循环队列满时:(rear+1)%maxSize == front
循环队列空时:rear == front
有效数据个数:(rear+maxSize-front)%maxSize
添加数据:先添加,后移动rear并取模
取数据:先取出,后移动front并取模
展示队列:for (int i = front; i < front + size(); i++)
方法:
实现方式2:链表
链表介绍:
链表是有序的列表,以节点方式存储数据,每个节点包含data域和next域,不(一定)连续存储,可选有无头指针