当前位置: 首页 > news >正文

数据结构-数组

一,数组基础及注意事项

1,用来储存一组相同的类型的数据.
2,在内存中,分配连续的空姐,数组创建时要指定容量(大小).
3,创建格式: 数据类型 []数组名  int[] arr = new int[10] int[] arr2 = {1,2,3,4}.
4,索引--访问数组时通过索引进行操作.
(注意:一定要理解索引的含义,在数据结构的学习中基本每次都用,索引简单的可以理解为,待插入元素,即,还没有赋值的第一个元素.)
5.索引从0开始,最大为数组名.length-1;
6,常见的错误: NullPointException ArrayIndexOutOfBoundsException 即我们常说的空指针h=和越界.
7,常见的数组:字符串,对象数组,哈希表

二,演示数组的使用,及数组的方法使用

使用数组时,最重要的就是数组的 索引 ,通过索引可以对数组进行改和查操作。
接下来用图 来演示
1,向数组中添加元素
2,向指定位置添加元素

3,向数组头添加元素
4,获取指定位置的元素和修改指定位置的元素
5,包含、搜索和删除元素

首先:对int类型的数组进行操作

接下来让我们手撕代码.:

import java.util.Arrays;
import java.util.Random;// 封装属于自己的数组
public class MyArray {private int[] data; // 底层数据结构private int size;// 用来保存实际存放元素的个数public MyArray() {this(100);}public MyArray(int capacity) {this.data = new int[capacity];this.size = 0;}// 判断数组是否为空public boolean isEmpty() {return this.size == 0;}// 获取数组实际存放元素的个数public int getSize() {return this.size;}// 对数组进行操作/** 1、增加的方法发现:this.size指向待插入元素的位置,因此,可以在this.size位置增加元素在头部增加: 1》 将数组中的元素后移,2》 将val添加到索引为0的位置* 在任意位置添加*//*** 在尾部添加** @param val val*/public void addTail(int val) {add(this.size, val);}/*** 在头部添加** @param val val*/public void addHead(int val) {add(0, val);}/*** 在任意位置添加** @param position 插入的位置* @param val      插入的值*/public void add(int position, int val) {if (position < 0 || position > this.size) {throw new IllegalArgumentException("position is invalid");}for (int i = this.size - 1; i >= position; i--) {this.data[i + 1] = this.data[i];}this.data[position] = val;this.size += 1;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();for (int i = 0; i < this.size; i++) {sb.append(this.data[i] + ",");}String result = sb.toString();return result.substring(0, result.length() - 1);}//获取指定位置的元素public int getElementByIndex(int index) {if (index < 0 || index >= this.size) {throw new IllegalArgumentException("index is invalid");}return this.data[index];}// 修改指定位置的元素public void setElementByIndex(int index, int val) {if (index < 0 || index >= this.size) {throw new IllegalArgumentException("index is invalid");}this.data[index] = val;}// cotains 用来判断数组中是否包含指定的元素public boolean contains(int searchVal) {for (int i = 0; i < this.size; i++) {if (this.data[i] == searchVal) {return true;}}return false;}// 查找指定元素在数组中的索引public int findIndex(int searchVal) {for (int i = 0; i < this.size; i++) {if (this.data[i] == searchVal) {return i;}}return -1;}// 删除数组中最后一个元素public int removeFromTail() {if (isEmpty()) {throw new IllegalArgumentException("this array is null!");}return this.data[--this.size];}// 删除数组中的第一个元素public int removeFromHead() {if (isEmpty()) {throw new IllegalArgumentException("this array is null!");}// 1、先保存数组中的第一个元素int result = this.data[0];// 2、将数组从索引为1的位置进行前移for (int i = 1; i < this.size; i++) {this.data[i - 1] = this.data[i];}this.size--;return result;}// 删除指定位置的元素public int removeByIndex(int index) {if (index < 0 || index >= this.size) {throw new IllegalArgumentException("index is invalid!");}int result = this.data[index];// 从索引为index位置的元素进行前移for (int i = index; i < this.size - 1; i++) {this.data[i] = this.data[i + 1];}this.size--;return result;}// 删除指定的元素public void remove(int val) {for (int i = 0; i < this.size; ) {if (this.data[i] == val) {// 删除元素---将后面的元素前移,然后更新sizefor (int j = i; j < this.size - 1; j++) {this.data[j] = this.data[j + 1];}this.size -= 1;} else {i++;}}}

}

我们要进行任意数据类型的数组,这时就要使用泛型来进行操作.

接下来让我们手撕代码.在上述我们自己写的int类型数组进行修改,添加泛型.

import java.util.Random;// 封装属于自己的数组,使用泛型
public class MyArray2<T> {private T[] data; // 底层数据结构private int size;// 用来保存实际存放元素的个数private int capacity; // 表示容积public MyArray2() {this(100);}public MyArray2(int capacity) {this.capacity = capacity;this.data = (T[]) new Object[this.capacity];this.size = 0;}// 获取容积的方法public int getCapacity() {return this.capacity;}// 判断数组是否为空public boolean isEmpty() {return this.size == 0;}// 获取数组实际存放元素的个数public int getSize() {return this.size;}// 对数组进行操作/** 1、增加的方法发现:this.size指向待插入元素的位置,因此,可以在this.size位置增加元素在头部增加: 1》 将数组中的元素后移,2》 将val添加到索引为0的位置* 在任意位置添加*//*** 在尾部添加** @param val val*/public void addTail(T val) {add(this.size, val);}/*** 在头部添加** @param val val*/public void addHead(T val) {add(0, val);}/*** 在任意位置添加** @param position 插入的位置* @param val      插入的值*/public void add(int position, T val) {if (position < 0 || position > this.size) {throw new IllegalArgumentException("position is invalid");}// 在增加之前,判断数组是否已满,如果已满,要进行扩容if (this.size == this.capacity) {// 扩容操作resize(this.capacity*2);}for (int i = this.size - 1; i >= position; i--) {this.data[i + 1] = this.data[i];}this.data[position] = val;this.size += 1;}// 改变容积的方法private void resize(int newCapacity) {System.out.println("--------resize--------");// 2、 创建一个新数组T[] newArr = (T[]) new Object[newCapacity];// 3、将原来数组的内容转移到新数组for (int i = 0; i < this.size; i++) {newArr[i] = this.data[i];}// 4、将newArr赋值给 this.datathis.data = newArr;// 5、将newCapacity 赋值给this.capacitythis.capacity = newCapacity;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();for (int i = 0; i < this.size; i++) {sb.append(this.data[i] + ",");}String result = sb.toString();return result.substring(0, result.length() - 1);}//获取指定位置的元素public T getElementByIndex(int index) {if (index < 0 || index >= this.size) {throw new IllegalArgumentException("index is invalid");}return this.data[index];}// 修改指定位置的元素public void setElementByIndex(int index, T val) {if (index < 0 || index >= this.size) {throw new IllegalArgumentException("index is invalid");}this.data[index] = val;}// cotains 用来判断数组中是否包含指定的元素public boolean contains(T searchVal) {for (int i = 0; i < this.size; i++) {if (this.data[i].equals(searchVal)) {return true;}}return false;}// 查找指定元素在数组中的索引public int findIndex(T searchVal) {for (int i = 0; i < this.size; i++) {if (this.data[i].equals(searchVal)) {return i;}}return -1;}// 删除数组中最后一个元素public T removeFromTail() {return removeByIndex(this.size-1);}// 删除数组中的第一个元素public T removeFromHead() {return removeByIndex(0);}// 删除指定位置的元素public T removeByIndex(int index) {if (index < 0 || index >= this.size) {throw new IllegalArgumentException("index is invalid!");}T result = this.data[index];// 从索引为index位置的元素进行前移for (int i = index; i < this.size - 1; i++) {this.data[i] = this.data[i + 1];}this.size--;if(this.size <= this.capacity/2 && this.capacity/2>1){resize(this.capacity/2);}return result;}// 删除指定的元素public void remove(int val) {for (int i = 0; i < this.size; ) {if (this.data[i].equals(val)) {// 删除元素---将后面的元素前移,然后更新sizefor (int j = i; j < this.size - 1; j++) {this.data[j] = this.data[j + 1];}this.size -= 1;} else {i++;}}// 删除之后,进行判断是否要进行缩容,如果需要缩容,缩到原容积的1/2if(this.size <= this.capacity/2 && this.capacity/2>1){resize(this.capacity/2);}}
}

代码较长希望有心人可以看完.

三,数组的复杂度分析.

我们对数组的逻辑有了简单的了解,就对数组的复杂度进行分析,后面可以通过比较复杂度,来选择合适的数据结构来储存数据.

1,分析动态数组的时间复杂度

(1),添加操作

 1,addLast(e) O(n)

2,addFirst(e)  O(1)  渐进时间复杂度

3,add(index,e) O(n^2) 描述n趋近于无穷的情况

(2),添加操作

(3),删除操作

(4),修改操作

(5),查找操作

(6) 综合

http://www.lryc.cn/news/305276.html

相关文章:

  • 【Java程序设计】【C00279】基于Springboot的智慧外贸平台(有论文)
  • C#,计算几何,计算机图形学(Computer Graphics)洪水填充算法(Flood Fill Algorithm)与源代码
  • C# 实现网页内容保存为图片并生成压缩包
  • C#_事件简述
  • C语言:指针(一)
  • 【leetcode刷题之路】面试经典150题(3)——哈希表+区间
  • 群晖NAS DSM7.2.1安装宝塔之后无法登陆账号密码问题解决
  • 9、使用 ChatGPT 的 GPT 制作自己的 GPT!
  • 企业微信应用开发:使用Cpolar域名配置进行本地接口回调的调试指南
  • js 可选链运算符(?.)空值合并运算符(??)逻辑空赋值运算符(??=)
  • vue 手势解锁功能
  • 介绍 CI / CD
  • Stable Diffusion 3 Early Preview发布
  • 【解决(几乎)任何机器学习问题】:特征选择
  • 24 双非计算机秋招总结
  • 用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增
  • 【初中生讲机器学习】12. 似然函数和极大似然估计:原理、应用与代码实现
  • 【达梦数据库】查看pesg回滚段信息的视图和SQL
  • UML---活动图
  • 编程笔记 Golang基础 018 常量与变量
  • 如何使用Douglas-042为威胁搜索和事件应急响应提速
  • 华为配置WLAN AC和AP之间VPN穿越示例
  • 跨语言的序列化与反序列化
  • 软考-中级-系统集成2023年综合知识(三)
  • 五、使用脚手架
  • 抛弃chatgpt,使用微软的Cursor提升coding效率
  • uniapp插件uViewplus的使用(涉及TS下的问题)
  • google浏览器chrome无法访问localhost等本地虚拟域名的解决方法
  • (2.2w字)前端单元测试之Jest详解篇
  • 【C++私房菜】面向对象中的多态