1.数据结构和算法
1.数据结构是一门研究组织数据方式的学科。(如果有效和高效的组织数据)。
2.数据结构是算法的基础。
3.程序=数据结构+算法。
2.线性结构和非线性结构
数据结构包括:线性结构和非线性结构
线性结构:
1.线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。
2.线性结构有顺序存储结构和链式存储结构。
顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的。
链式存储的线性表称为链表,链表中存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的
地址信息。
3.线性结构常见的有:数组、队列、链表和栈。
非线性结构:
非线性结构包括:二维数组、多维数组、广义表、树结构、图结构
3.稀疏数组
当一个二维数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。因为原本的
二维数组记录了很多没有意义的数据(比如二维数组中大部分元素为0),使用稀疏数组可以节约空间。
稀疏数组的处理方式是:
1.记录数组一共有几行几列,有多少不同的值。
2.把具有不同值元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。
注意:稀疏数组的行不确定(行数是原始数组存在的不同数据值有多少个),列固定是3列。
二维数组转稀疏数组思路:
1.先遍历原始二维数组,得到数组中值的总个数sum。
2.根据sum创建稀疏数组sparseArr int[sum+1][sum]。
3.将原始二维数组的数据值存入稀疏数组中。
稀疏数组转二维数组思路:
1.读取稀疏数组第一行数据,创建对应原始二维数组。
2.读取稀疏数组后面几行数据,根据下标赋值给二维数组。
4.稀疏数组代码实践
1.原始数组转稀疏数组
package com.ls.sparse;
/**
* @pageage: com.ls.sparse
* @description:稀疏数组
* @author: dongdong.li
* @create: 2022/1/12 14:33
*/
public class SparseArrayMain {
public static void main(String[] args) {
//1.创建8*8棋盘
int[][] checkerboard = new int[8][8];
//1表示黑子 2表示白字
checkerboard[1][1] = 1;
checkerboard[2][3] = 2;
checkerboard[3][3] = 2;
//记录原始数组的有效数据
int validData = 0;
//2.输出打印原始数组
for (int i = 0; i < checkerboard.length; i++) {
for (int j = 0; j < checkerboard[i].length; j++) {
if (checkerboard[i][j] != 0) {
validData++;
}
System.out.print(checkerboard[i][j] + "\t");
}
System.out.println("");
}
System.out.println("原始数组的有效数据总数:" + validData);
System.out.println("-----------------------------------");
//3.根据validData创建稀疏数组
int[][] sparseArray = new int[validData + 1][3];
//稀疏数组第一行记录原始数组的行列和有效数据个数
sparseArray[0][0] = checkerboard.length;
sparseArray[0][1] = checkerboard.length;
sparseArray[0][2] = validData;
//稀疏数组从第二行开始记录有效数据的位置所以count=1
int count = 1;
//4.稀疏数组记录原始数组有效数据的位置
for (int i = 0; i < checkerboard.length; i++) {
for (int j = 0; j < checkerboard[i].length; j++) {
if (checkerboard[i][j] != 0) {
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = checkerboard[i][j];
count++;
}
}
}
//5.输出稀疏数组
for (int i = 0; i < sparseArray.length; i++) {
System.out.print(sparseArray[i][0] + "\t" + sparseArray[i][1] + "\t" + sparseArray[i][2]);
System.out.println("");
}
}
}
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 2 0 0 0 0
0 0 0 2 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
原始数组的有效数据总数:3
-----------------------------------
8 8 3
1 1 1
2 3 2
3 3 2
2.稀疏数组转原始数组
package com.ls.sparse;
/**
* @pageage: com.ls.sparse
* @description:
* @author: dongdong.li
* @create: 2022/1/12 15:12
*/
public class SparseArrayMain2 {
public static void main(String[] args) {
int[][] sparseArray = new int[4][3];
sparseArray[0][0] = 8;
sparseArray[0][1] = 8;
sparseArray[0][2] = 3;
sparseArray[1][0] = 1;
sparseArray[1][1] = 1;
sparseArray[1][2] = 1;
sparseArray[2][0] = 2;
sparseArray[2][1] = 3;
sparseArray[2][2] = 2;
sparseArray[3][0] = 3;
sparseArray[3][1] = 3;
sparseArray[3][2] = 2;
System.out.println("稀疏数组:");
for (int i = 0; i < sparseArray.length; i++) {
System.out.print(sparseArray[i][0] + "\t" + sparseArray[i][1] + "\t" + sparseArray[i][2]);
System.out.println("");
}
System.out.println("-----------------------");
//稀疏数组转原始二维数组
//1.根据稀疏数组第一行构建原始数组
int[][] checkerboard = new int[sparseArray[0][0]][sparseArray[0][1]];
//2.给原始数组赋值
for (int i = 1; i < sparseArray.length; i++) {
checkerboard[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
System.out.println("转换后的原始数组:");
//3.输出打印转换后的二维数组
for (int i = 0; i < checkerboard.length; i++) {
for (int j = 0; j < checkerboard[i].length; j++) {
System.out.print(checkerboard[i][j] + "\t");
}
System.out.println("");
}
}
}
稀疏数组:
8 8 3
1 1 1
2 3 2
3 3 2
-----------------------
转换后的原始数组:
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 2 0 0 0 0
0 0 0 2 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
5.队列
队列是一个有序列表,可以是数组或是链表来实现。
特点:先进先出。
1.数组模拟实现队列
package com.ls.sparse;
import java.util.Scanner;
/**
* @pageage: com.ls.sparse
* @description:数组模拟队列
* @author: dongdong.li
* @create: 2022/1/14 11:31
*/
public class ArrayQueueMain {
public static void main(String[] args) {
ArrayQueue arrayQueue = new ArrayQueue(5);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("s:显示队列");
System.out.println("a:队列添加元素");
System.out.println("g:获取队列元素");
System.out.println("h:获取队列头部元素");
System.out.println("e:退出程序");
char c = scanner.next().charAt(0);
switch (c){
case 's':
arrayQueue.showQueue();
break;
case 'a':
System.out.println("请输入要添加的数据");
int data = scanner.nextInt();
System.out.println(data);
arrayQueue.addQueue(data);
break;
case 'g':
System.out.println("从队列中获取元素:"+arrayQueue.getQueue());
break;
case 'h':
System.out.println("队列头元素:"+arrayQueue.getQueueHeaderData());
break;
case 'e':
System.exit(-1);
break;
}
}
}
}
class ArrayQueue{
//数组长度
private int maxSize;
//表示队列头
private int headN;
//表示队列尾
private int tailN;
//数组 模拟队列
private int[] arr;
public ArrayQueue(int maxSize){
//初始化数组长度
this.maxSize = maxSize;
//初始队列头
this.headN = -1;
//初始队列尾
this.tailN = -1;
//初始数组 模拟队列
this.arr = new int[maxSize];
}
//检测队列是否为空
public boolean isEmpty(){
return this.headN == this.tailN;
}
//检测队列是否已满
public boolean isFull(){
return tailN == maxSize - 1;
}
//给队列添加元素
public void addQueue(int data){
if(isFull()){
throw new RuntimeException("队列已满,无法添加");
}
this.tailN++;
this.arr[this.tailN]= data;
}
//队列获取元素
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
this.headN++;
return this.arr[this.headN];
}
//获取队列头元素
public int getQueueHeaderData(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return this.arr[this.headN+1];
}
//打印队列
public void showQueue(){
for(int i=0;i<this.arr.length;i++){
System.out.print(this.arr[i]+"\t");
}
System.out.println("");
}
}
注意:目前该代码存在的问题
1.数组只能单次使用,没有到达复用的效果。