数据结构与算法(Java实现)
我的学习资料:
视频:尚硅谷Java数据结构与java算法(Java数据结构与算法)
书籍:《大话数据结构》
笔记中包括学习的内容,代码,同时自己总结了知识点速记(部分会带页内跳转,可点击跳转)供快速回顾和记忆学到的知识点。
三、链表(Linked List)之单链表
3.1链表和单链表的定义
- 线性表的顺序存储结构(即顺序表)用一段地址连续的存储单元依次存储线性表的数据元素,优点是可以通过索引快速找到对应元素,实现了随机访问,但是扩容比较麻烦(需要再重新分配一个更大的空间,把数据全部复制过去),最大的缺点就是插入和删除时需要移动大量元素。
- 因此出现了线性表的链式存储结构(链表),它用一组任意的存储单元(连续的或不连续的)存储线性表的数据元素。(即链表的存储单元不一定连续)。
- 链表为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对于元素ai,除了存储本身的信息(也叫数据域,即Data域)之外,还需要存储一个指示它直接后继元素位置的信息(也叫指针域,next域),这两个域合在一起就是结点。
- 多个结点链接成一个线性表,即链表。
- 如果线性链表的每个结点只有一个next指针域,则称作单链表。
- 我们把单链表中第一个结点的存储位置叫做头指针,最后一个结点指针为空(通常用NULL或者"^"来表示)。它的内存结构如图:
- 链表有带头结点的,有不带头结点的。头结点的指针域指向第一个结点。他们的逻辑结构图如图:
3.2 单链表的实现
按照序号顺序添加新结点addByOrder:
- 辅助指针后移,找到要添加的位置。比较data域中的序号,新结点no值的>=temp.next.no则指针后移
0.2 非线性结构
常见的有:二维数组,多维数组,广义表,树,图
一、稀疏( sparsearray)数组
1.1 实际需求
对于一个五子棋盘上棋子的情况,可以使用二维数组记录,0表示无棋子,1和2分别表示两种颜色的棋子,因为该二维数组的很多值是默认值 0 ,因此记录了很多没有意义的数据,我们将其转为稀疏数组进行存储。
1.2 介绍
1.2.1 基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
1.2.2 处理方法及举例
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
- 具体操作:
第1行:记录原始二维数组的行数,列数,非0元素(或者说有效数据)的总个数
- 第1列:原始二维数组的行数
- 第2列:原始二维数组的列数
- 第3列:原始二维数组的非0元素的个数
剩余几行:记录原始二维数组非0元素(或者说有效数据)在原始二维数组的下标(横纵坐标)及它的值
-
第1列:非0元素(有效数据)的横坐标
-
第2列:非0元素(有效数据)的纵坐标
-
第3列:非0元素(有效数据)的值
-
二维数组——>稀疏数组举例:
在下面的棋盘中,原始二维数组规模是6×7,转化为稀疏数组规模变为9×3(注意数组的坐标是从0开始的,但我们可能习惯描述第几行是从第1行开始的)
1. 搞定第一行
因为原始规模6*7,即【6行7列8个非零值】,因此在稀疏数组第1行(注意行坐标是0)依次填入【6,7,8】
2. 剩余的元素按照“行”的方式遍历,依次填入。
比如第一个非零元素是22,横纵坐标【0,3】因此在稀疏数组下一行依次填入它的坐标及它的值【0,3,22】
接下来按照行遍历,应该依次填入的元素是15,11,17,-6,39,91,28,完成稀疏数组。
1.3 应用实例
1.3.1实例说明
- 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
- 把稀疏数组存盘,并且可以重新恢复原来的二维数组数
二维数组——>稀疏数组的思路
- 遍历 原始的二维数组,得到有效数据的个数 sum
- 根据sum 就可以创建 稀疏数组 sparseArr int[sum + 1 ] [ 3 ]
- 将二维数组的有效数据数据存入到 稀疏数组
稀疏数组——>原始的二维数组的思路
- 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11][11]
- 在读取稀疏数组后几行的数据,并赋给 原始的二维数组即可.
1.3.2 代码实现
package dataStructures;
import java.util.Arrays;
public class GoBang {
public static int BTsize=11;
int[][] realCheckBoard = new int[BTsize][BTsize];
int[][] sparseArray;
int count=0;
public static void main(String[] args) {
GoBang gb = new GoBang();
gb.realCheckBoard[1][2]=1;
gb.realCheckBoard[2][3]=2;
System.out.println();
for (int[]a1:gb.realCheckBoard
) {
System.out.println();
for (int a2:a1
) {
System.out.print(a2+" ");
}
}
int[][] array1 =gb.realCheckBToSparseArray();
int[][] array2 = gb.sparseArrayToRealCheckBT();
}
public GoBang(){
}
public GoBang(int[][] realCheckBoard) {
this.realCheckBoard = realCheckBoard;
}
public int[][] realCheckBToSparseArray(){
System.out.println();
System.out.println("得到稀疏数组为:");
//遍历二维数组找到非0元素值的个数,用count表示
for (int i=0;i<realCheckBoard.length;i++){
for (int j=1; j<realCheckBoard[i].length;j++){
if (realCheckBoard[i][j]!=0){
count++;
}
}
}
sparseArray = new int[count + 1][3];
sparseArray[0][0] = BTsize;
sparseArray[0][1] = BTsize;
sparseArray[0][2] = count;
if (count!=0) {