数据结构与算法:数据结构基础
目录
数组
定义
形式
顺序存储
基本操作
读取元素
更新元素
插入元素
删除元素
扩容
初始化
时机
步骤
优劣势
链表
定义
单向链表
特点
双向链表
随机存储
基本操作
查找节点
更新节点
插入节点
删除元素
数组VS链表
栈与队列
栈
定义
基本操作
1.入栈
2.出栈
队列
定义
基本操作
1.入队
2.出队
栈和队列的运用
1.栈的应用
2.队列的运用
3.双端队列
4.优先队列
散列表
定义
哈希函数
实现
读写操作
写操作
读操作
哈希冲突
解决办法
数组
定义
有限个相同类型变量所组成的有序集合,数组中每个变量都被称为元素。数组是最简单、最常见的数据结构。
形式
以整形数组为例:

数组中的每一个元素也有着自己的下标,只不过这个下标从0开始,一直到数组长度-1。
顺序存储
数组的另一个特点,是在内存中顺序存储,因此可以很好地实现逻辑上的顺序表。
内存是由一个个连续的内存单元组成的,每一个内存单元都有自己的地址。在 这些内存单元中,有些被其他数据占用了,有些是空闲的。
数组中的每一个元素,都存储在小小的内存单元中,并且元素之间紧密排列, 既不能打乱元素的存储顺序,也不能跳过某个存储单元进行存储

不同类型的数组,每个元素所占的字节个数也不同
基本操作
读取元素
读取元素是最简单的操作。由于数组在内存中顺序存储,所以 只要给出一个数组下标,就可以读取到对应的数组元素
注意:
通过下标读取数组,下标必须在数组长度范围内,否则会出现数组越界
示例:
int[] array = new int[]{3,1,2,5,4,9,7,2};System.out.println(array[3]);
更新元素
把数组中某一个元素的值替换为一个新值,直接利用数组下标,就可以把新值赋给该元素。
示例:
1. int[] array = new int[]{3,1,2,5,4,9,7,2};
2. // 给数组下标为5的元素赋值
3. array[5] = 10;
4. // 输出数组中下标为5的元素
5. System.out.println(array[5]);
插入元素
数组的实际元素数量有可能小于数组的长度,所以存在3种情况:
1.尾部插入
是最简单的情况,直接把插入的元素放在数组尾部的空闲位置即 可,等同于更新元素的操作

2.中间插入
由于数组的每一个元素都有其固定下标,所以不得 不首先把插入位置及后面的元素向后移动,腾出地方,再把要插入的元素放到对应 的数组位置上。

3.超范围插入
可以创建一个新数组,长度是旧数组的2倍,再把旧数组中的元素统统复制 过去,这样就实现了数组的扩容。

删除元素
数组的删除操作和插入操作的过程相反,如果删除的元素位于数组中间,其后 的元素都需要向前挪动1位。

/**
2. * 数组删除元素
3. * @param index 删除的位置
4. */
5. public int delete(int index) throws Exception {
6. //判断访问下标是否超出范围
7. if(index<0 || index>=size){
8. throw new IndexOutOfBoundsException("超出数组实际元素范围!");
9. }
10. int deletedElement = array[index];
11. //从左向右循环,将元素逐个向左挪1位
12. for(int i=index; i<size-1; i++){
13. array[i] = array[i+1];
14. }
15. size--;
16. return deletedElement;
17. }
扩容
初始化
如果参数等于0,则将数组初始化为一个空数组,
如果不等于0,将数组初始化为一个容量为10的数组
时机
当数组的大小大于初始容量的时候(比如初始为10,当添加第11个元素的时候),就会进行扩容,新的容量为旧的容量的1.5倍
步骤
1:定义一个新数组,新数组的长度要比原数组增加或者减小;
2:将原数组中的元素拷贝到新数组中;
3:将原数组的名称变量指向新数组
优劣势
优点:拥有非常高效的随机访问能力,只要给出下标,就 可以用常量时间找到对应元素
缺点:由于数 组元素连续紧密地存储在内存中,插入、删除元素都会导致大量元素被迫移动,影响效率
适合的是读操作多、写操作少的场景。
链表
定义
是一种在物理上非连续、非顺序的数据结构,由若干节点组成。
单向链表
每一个节点又包含两部分,一部分是存放数据的变量data,另一部 分是指向下一个节点的指针next。
private static class Node {
int data;
Node next;
}
链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指 针指向空。
特点
与数组按照下标来随机寻找元素不同,对于链表的其中一个节点A,我们只能根 据节点A的next指针来找到该节点的下一个节点B,再根据节点B的next指针找到下 一个节点C……
双向链表
双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指 针,还拥有指向前置节点的prev指针

随机存储
链表在内存中的存储方式则 是随机存储。
内存分配方式:链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位 置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间

基本操作
查找节点
在查找元素时,链表不像数组那样可以通过下标快速进行定位,只能从头节点开始向后一个一个逐步查找。
例如给出一个链表,需要查找从头节点开始的第3个节点。
第1步,将查找的指针定位到头节点
第2步,根据头节点的next指针,定位到第2个节点。
第3步,根据第2个节点的next指针,定位到第3个节点,查找完毕。
更新节点
如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数 据替换成新数据即可。

插入节点
与数组类似,链表插入节点时,同样分为3种情况:
1.尾部插入:把最后一个节点的next指针指向新插入的节点即 可

2.头部插入:把新节点的next指针指向原先的头节点;把新节点变为链表的头节点

3.中间插入:新节点的next指针,指向插入位置的节点;插入位置前置节点的next指针,指向新节点。

只要内存空间允许,能够插入链表的元素是无穷无尽的,不需要像数组那样考 虑扩容的问题
Node insertedNode = new Node(data);
if(size == 0){
//空链表
head = insertedNode;
last = insertedNode;
} else if(index == 0){
//插入头部
insertedNode.next = head;
head = insertedNode;
}else if(size == index){
//插入尾部
last.next = insertedNode;
last = insertedNode;
}else {
//插入中间
Node prevNode = get(index-1);
insertedNode.next = prevNode.next;
prevNode.next = insertedNode;
}
size++;
删除元素
链表的删除操作同样分为3种情况:
1.尾部删除:把倒数第2个节点的next指针指向空即可

2.头部删除:把链表的头节点设为原先头节点的next指针即可

3.中间删除:把要删除节点的前置节点的next指针,指向要删除元 素的下一个节点即可。

Java拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点 会被自动回收。
// 头节点指针
private Node head;
// 尾节点指针
private Node last;
// 链表实际长度
private int size;Node removedNode = null;
if(index == 0){
//删除头节点
removedNode = head;
head = head.next;
}else if(index == size-1){
//删除尾节点
Node prevNode = get(index-1);
removedNode = prevNode.next;
prevNode.next = null;
last = prevNode;
}else {
//删除中间节点
Node prevNode = get(index-1);
Node nextNode = prevNode.next.next;
removedNode = prevNode.next;
prevNode.next = nextNode;
}
size--;
数组VS链表

数组的优势在于能够快速定位元素, 对于读操作多、写操作少的场景更合适;
链表的优势在于能够灵活地进行插入和删除操 作,如果需要在尾部频繁插入、删除元素,用链表更合适一些
栈与队列
栈
定义
是一种线性数据结构。最早进入的元素存放的位置叫作栈底(bottom),最后进入的元素存放的位置叫作栈顶

数组实现:

链表实现:

基本操作
1.入栈

2.出栈
数组为例:

队列
定义
基本操作
1.入队
2.出队

栈和队列的运用
1.栈的应用
实现递归的逻辑,就可以用栈来代替,因为栈可以回溯方法的调用链
面包屑导航,使用户在浏览页面时可以轻松地回溯到上一级或更上一级页面
2.队列的运用
在多线程中,争夺公平锁的等待队列,就是按照访问顺序来决定线程在队列中的次序的
3.双端队列
4.优先队列
散列表
定义

哈希函数

实现
以hashMap为例:
index = HashCode (Key) % Array.length
读写操作
写操作
读操作
哈希冲突
解决办法
相关文章:
数据结构与算法:数据结构基础
目录 数组 定义 形式 顺序存储 基本操作 读取元素 更新元素 插入元素 删除元素 扩容 初始化 时机 步骤 优劣势 链表 定义 单向链表 特点 双向链表 随机存储 基本操作 查找节点 更新节点 插入节点 删除元素 数组VS链表 栈与队列 栈 定义 基本操作…...
virtualbox虚拟机中安装FreeDOS系统和DJGPP编译环境
一、安装FreeDOS系统 1、从官网下载FreeDOS系统镜像,下载的压缩包中包含两个文件:后缀为.iso和.img的镜像 下载页面 http://www.freedos.org/download/ 直接下载链接 https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.…...
JAVASE事件监听
代码: import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner;import javax.swing.JButton; import javax.…...
ubuntu14.04改静态ip
现在可能已经用ubuntu14.04的人已经不多了,这里讲一下Ubuntu14.04怎么改静态ip 第一步:输入ifconfig查看ip和子网掩码 第二步:输入route -n查看网关 上面ip是192.168.88.136,子网掩码是255.255.255.0,网关是192.168.…...
“文件的上传与下载:实现与优化“
目录 引言1.文件的上传2.文件的下载3. JRebel安装使用4. 文件批量上传总结 引言 在开发过程中,文件的上传与下载是常见的需求。本篇博客将以CSND为例,介绍文件上传与下载的常见方式,以及如何通过优化提升性能和用户体验。 1.文件的上传 使…...
uboot顶层Makefile前期所做工作说明三
一. uboot顶层 Makefile文件 uboot顶层 Makefile,就是 uboot源码工程的根目录下的 Makefile文件。 本文继续对 uboot顶层 Makefile的前期准备工作进行介绍。续上一篇文章内容的学习,如下: uboot顶层Makefile前期所做工作说明二_凌肖战的博…...
Mysql树形表的两种查询方案(递归与自连接)
你有没有遇到过这样一种情况: 一张表就实现了一对多的关系,并且表中每一行数据都存在“爷爷-父亲-儿子-…”的联系,这也就是所谓的树形结构 对于这样的表很显然想要通过查询来实现价值绝对是不能只靠select * from table 来实现的࿰…...
text-align和text-align-last的属性值
text-algin 文本对齐方式: (1)left:左对齐; (2)right:右对齐; (3)center:居中对齐; (4)start&…...
SpringMVC的注解、参数传递、页面跳转
一.SpringMvc常用注解 常用注解 RequestMapping:RequestMapping注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上。 RequestParam:RequestParam主要用于将请求参数区域的数据映射到控制层方法的参数上 ModelAttr…...
OAK相机:启动报错X_LINK_DEVICE_NOT_FOUND
OAK相机:启动报错X_LINK_DEVICE_NOT_FOUND 环境报错原因与解决未设置 udev 规则USB崩溃排线接触不良或相机模块时钟干扰 环境 硬件: 4✖️OV9782相机模组OAK-FFC-4P驱动模组笔记本电脑 软件: Ubuntu18.04python 3.9depthai 2.21.2.0 报错…...
Python异常处理——走BUG的路,让BUG无处可走
作者:Insist-- 个人主页:insist--个人主页 本文专栏:Python专栏 专栏介绍:本专栏为免费专栏,并且会持续更新python基础知识,欢迎各位订阅关注。 目录 一、了解python异常 1、BUG 单词的由来 2、什么是异…...
如何解决iOS打包工具AppUploader登录权限问题?
摘要:在iOS技术博主的指导下,了解如何解决使用AppUploader打包时出现的权限问题。本文将深入探讨此问题,为你提供详细的解决方案。 引言: 作为iOS开发者,我们经常需要使用工具来打包和上传应用程序。AppUploader 是一…...
leetcode分类刷题:基于数组的双指针(四、小的移动)
leetcode上有些题是真的太难了,正常读题之后完全想不到要用双指针来求解,本次博客总结的题目是双指针初始时位于数组两端,哪个元素小就移动哪个指针 11. 盛最多水的容器 1、这道题放在42. 接雨水的相似题目里,可能是因为它们都有相…...
eclipse
快捷键 F4: 继承树 F3: 查看变量、方法、类的定义, 跳到光标所在标识符的定义代码。(Ctrl左键) CtrlShiftG: 在工作空间中查找引用了光标所在标识符的位置。与F3相反的快捷键。当按类定义进行阅读时,当前类方法或者函数在被哪些地方调用 controlTAB: 切…...
VIT中的einops包详解
‘’‘einops有三个常用方法:rearrange,repeat,reduce’‘’ rearrange的操作相当于转置 rearrange(image,‘h w c -> w h c’) 高和宽转置 path ../data/cat_and_mouse.jpg image cv2.imread(path) h,w,c image.shape # shape第一个值是h,第二个是w image…...
目标检测笔记(十三): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程))
文章目录 一、目标检测介绍二、YOLOv5介绍2.1 和以往版本的区别 三、代码获取3.1 视频代码介绍 四、环境搭建五、数据集准备5.1 数据集转换5.2 数据集验证 六、模型训练七、模型验证八、模型测试九、评价指标 一、目标检测介绍 目标检测(Object Detectionÿ…...
【数据结构】设计环形队列
环形队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 环形队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列…...
无涯教程-JavaScript - COUPDAYSNC函数
描述 COUPDAYSNC函数返回从结算日期到下一个息票日期的天数。 语法 COUPDAYSNC (settlement, maturity, frequency, [basis])争论 Argument描述Required/OptionalSettlement 证券的结算日期。 证券结算日期是指在发行日期之后将证券交易给买方的日期。 RequiredMaturity 证…...
python 随机生成emoji表情
问答板块觉得比较有意思的问题 当时搜了些网上的发现基本都不能用,不知道是版本的问题还是咋的就开始自己研究 python随机生成emoji 问题的产生解决官网文档数据类型实现思路实现前提:具体实现: 其他常见用法插入 Emoji 表情:解析…...
python关闭指定进程以excel为例
先说下环境: Excel版本: Python2.7.13和Python3.10.4并存。 2、打开两个excel工作簿 看进程是这样的: 3、用python编程kill进程 # -*- coding: utf-8 -*- import os proc_nameEXCEL.EXE if __name__ __main__:os.system(taskkill /im {} /…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
