重新学习数据结构和算法(持续更新)

2024-01-14 13:40

本文主要是介绍重新学习数据结构和算法(持续更新),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 第一章 先给大家打个气
  • 第二章 初识数据结构和算法
    • 1.线性结构和非线性结构
    • 2.概览几种常见的数据结构
    • 3.概览几种常见的算法思想
  • 第三章 稀疏数组
    • 1.引入稀疏数组
    • 2.二维数组转稀疏数组
    • 3.稀疏数组转二维数组
  • 第四章 队列
    • 1.队列的简介
    • 2.数组模拟队列
  • 总结


前言

为什么写这篇文章:数据结构和算法是程序的灵魂,强烈建议大家认真学好这门学科,无论是对今后的工作生活、还是找工作亦或者是自己的思维都有巨大的帮助。相信我,一定要好好学,即将走入社会的我决定好好补一补大学期间没认真学的这门课。我是我重学《数据结构和算法》的学习笔记,java版本,在这里分享给大家,互帮互助共同进步。2021年4月23日开始编写,后期持续更新。
适宜人群:认同数据结构和算法很重要的同学(有一定数据结构基础)
你将学习到:常见的数据结构和算法
条件:一台可以运行“hello world”的电脑(暗示你们需要java环境)、一颗有毅力的心
资料参考:尚硅谷《Java数据结构和算法》、网络

注意:本文为笔者的学习笔记,仅供学习使用,本文部分图片来源于网路,如有侵权,请联系笔者删除。

第一章 先给大家打个气

如果你不想当码农,那就花时间来研究下数据结构和算法!
当你真心想要做一件事的时候,整个宇宙都会帮助你,加油!

第二章 初识数据结构和算法

1.线性结构和非线性结构

在这里插入图片描述

  • 数据结构分为线性结构非线性结构
  • 线性结构又分为 顺序存储结构(数组)链式存储结构(链表)
  • 顺序存储的链式表又叫做顺序表,顺序表中的存储元素是连续的

2.概览几种常见的数据结构

下面列举了几种常见的数据结构,先大概看一下它们长什么样子,帅不帅美不美,有没有你相中的。
2.1 数组
特点:查询快、增删慢
衍生物:一维数组、二维数组、多维数组、稀疏数组(下一章)等
在这里插入图片描述

2.2 链表
特点:查询慢、增删快
衍生物:单向链表、双向链表、循环链表(也分单双)
在这里插入图片描述

2.3 栈
特点:先进后出
衍生物:数组实现的栈、链表实现的栈
在这里插入图片描述
2.4 队列
特点:先进先出
衍生物:数组实现的队列、链表实现的队列
在这里插入图片描述

2.5 树
衍生物:二叉树、完全二叉树、满二叉树、二叉排序树、B+树、平衡二叉树、红黑树等(仿佛心里一点B树都没有,有点小怕)
在这里插入图片描述

2.6 图
在这里插入图片描述

2.7 哈希表(散列表)
结构:数组+链表+红黑树(jdk1.8)
在这里插入图片描述

3.概览几种常见的算法思想

注意!!!这里看不懂没关系,直接跳(笔者编辑这里的时候也有很多不懂的,没事,慢慢来,等学完后面的章节后再回过头来看这里),现在你只需要浏览一两分钟就可以了,了解一下算法有哪些思想,混个耳熟
3.1 枚举
在这里插入图片描述
案例:百钱买百鸡问题
公鸡一个五块钱,母鸡一个三块钱,小鸡三个一块钱,现在要用一百块钱买一百只鸡,问公鸡、母鸡、小鸡各多少只?
3.2 递推
在这里插入图片描述
案例:兔子问题
定一对大兔子每月能生一对小兔子,且每对新生的小兔子经过一个月可以长成一对大兔子,具备繁殖能力,如果不发生死亡,且每次均生下一雌一雄,问一年后共有多少对兔子?
3.3 递归
在这里插入图片描述
案例:汉诺塔问题
源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
3.4 分治
在这里插入图片描述
案例:归并排序
3.5 动态规划
在这里插入图片描述
案例:背包问题
有 n 件物品和容量为 m 的背包,给出物品的重量以及价值。求解让装入背包的物品重量不超过背包容量且价值最大 。
3.6 贪心
在这里插入图片描述
案例:旅行推销员问题
给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。
3.7 回溯
在这里插入图片描述
案例:八皇后问题
在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
3.8 模拟
在这里插入图片描述

第三章 稀疏数组

好了,不劝退了,从这章开始我们认真学习

1.引入稀疏数组

提到数组,相信大家并不陌生,但稀疏数组是个什么玩意呢,我们先来看下面这个场景
在这里插入图片描述
这是一个五子棋棋盘,很容易想到用二维数据来记录棋盘信息,0代表没下,1代表一个人下的棋,2代表另一个人下的。现在要存储当前的棋盘信息,可用二维数组存,但发现一个问题,0很多(没下棋的地方),而下了棋的地方很少,就这样用一个二维数组来存储的话,属实有点浪费空间,我们能不能用一种方法,只记录有用的信息,比如棋盘的大小(行数和列数)、每个棋子的位置,于是稀疏数组来了。

当一个数组中大部分元素为0或为同一个值的数组时,可以使用稀疏数组。稀疏数组第一行记录总行数、总列数、有效数据数,后面几行记录的是每个有效数的行列位置和对应的值。

2.二维数组转稀疏数组

2.1 思路
第一步,遍历原始二维数组得到有效数据个数sum
第二步,根据sum创建稀疏数组sparseArr int[sum+1][3]
第三步,将二维数组中的有效数据存入到稀疏数组中
2.2 代码实现(强烈建议自己先动手,再对比)

public static int[][] toSparseArr(int[][] arr) {//第一步,遍历原始二维数组得到有效数据个数sumint row = arr.length;int col = arr[0].length;int sum = 0;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if (arr[i][j] != 0) {sum++;}}}//第二步,根据sum创建稀疏数组sparseArr int[sum+1][3]int[][] sparseArr = new int[sum + 1][3];//第三步,将二维数组中的有效数据存入到稀疏数组中//1 稀疏数组第一行赋值sparseArr[0][0] = row;sparseArr[0][1] = col;sparseArr[0][2] = sum;//2 有效数据存入到稀疏数组中int count = 1;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if (arr[i][j] != 0) {sparseArr[count][0] = i;sparseArr[count][1] = j;sparseArr[count][2] = arr[i][j];count++;}}}System.out.println("遍历输出稀疏数组");for (int i = 0; i < sparseArr.length; i++) {for (int j = 0; j < sparseArr[0].length; j++) {System.out.print(sparseArr[i][j] + " ");}System.out.println();}return sparseArr;}

3.稀疏数组转二维数组

3.1 思路
第一步,根据稀疏数组第一行记录的总行数、总列数创建出二维数组
第二步,从第二行开始,将稀疏数组中的各个有效数赋值给二维数组
3.2 代码实现(强烈建议自己先动手,再对比)

public static int[][] ToTwoArr(int[][] parseArr) {//第一步,根据稀疏数组第一行记录的总行数、总列数创建出二维数组int row = parseArr[0][0];int col = parseArr[0][1];int num = parseArr[0][2];int[][] arr = new int[row][col];//第二步,从第二行开始,将稀疏数组中的各个有效数赋值给二维数组for (int i = 1; i <= num; i++) {int row1 = parseArr[i][0];int col1 = parseArr[i][1];int value = parseArr[i][2];arr[row1][col1] = value;}System.out.println("遍历输出转化后的二维数组");for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[0].length; j++) {System.out.print(arr[i][j] + " ");}System.out.println();}return arr;}

第四章 队列

1.队列的简介

队列是一个有序表,可以用数组或链表来实现。遵循先入先出的原则。
它只允许在一端进行插入操作,在另一端进行删除操作。

2.数组模拟队列

2.1 思路
maxSize代表队列的最大长度,因为队列的输入输出是分别从前后端进行的,因此需要两个参数front和rear分别记录队头和队尾的下标,每取出一个数据front++,每存入一个数据rear++,如图所示
在这里插入图片描述
2.2 实现代码

public class ArrayQueue {private int maxSize;private int front;private int rear;private int[] arr;public ArrayQueue(int arrMaxSize) {maxSize = arrMaxSize;arr = new int[maxSize];front = -1;rear = -1;}public boolean isFull() {return rear == maxSize - 1;}public boolean isEmpty() {return front == rear;}public void add(int num) {if (isFull()) {throw new RuntimeException("添加失败,队列已满");} else {rear++;arr[rear] = num;}}public int get() {if (isEmpty()) {throw new RuntimeException("获取失败,空队列");} else {front++;return front;}}public void showQueue() {if (isEmpty()) {throw new RuntimeException("空队列");} else {int t = front + 1;while (t <= rear) {System.out.print(arr[t] + " ");t++;}}}public int peek() {if (isEmpty()) {throw new RuntimeException("空队列");} else {return arr[front + 1];}}
}

总结

这篇关于重新学习数据结构和算法(持续更新)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605343

相关文章

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,