java 数组算法_Java数据结构与算法分析 | 数组

本文介绍了Java中数组的基本特性和操作,包括数组的线性表性质、数据存储的连续性以及固定大小的特性。重点讲解了如何在数组中插入和删除元素,通过代码示例展示了动态扩容和数据移动的过程,同时提供了插入和删除操作的完整Java代码。
摘要由CSDN通过智能技术生成

GitHub代码分享

数组(Array)

数组是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。其特性有:

1、数组是一个线性表,每个线性表上的数据最多只有前和后两个方向。

2、数组的存储元素是连续的,此特性最大的优点是检索速度非常快,但是插入和删除效率很低,为了保证连续性需要做大量的数据搬移工作,下面会有代码示例来说明。

6ba35c15d53bd83a67a79d49a19f338a.png

3、数据的大小是固定的,因为在数组定义的时候,需要为它分配连续的内存空间,所以需要预先指定其大小。当存放的数据大于其大小时,我们需要重新分配一块更大的空间,把原来的数据复制过去。下面这段代码解释一个数组arr在必要的时候如何被扩容:int[] arr = new int[10];

...

// 下面我们决定扩大arr

int[] newArr = new int[arr.length * 2];

for(int i = 0, i < arr.length, i++){

newArr[i] = arr[i];

}

arr = newArr;

代码示例

插入数据public static String[] insert(String[] array, int index, String data) {

// 判断参数是否合法

if (array == null || array.length == 0 || index < 0 || index > array.length) {

throw new RuntimeException("参数不合法!");

}

// 复制出一个长度+1的数组

String[] newArray = Arrays.copyOf(array, array.length + 1);

// 将数据从index开始往后移1位;若index为最后一位,则无需移动

if (array.length > index) {

System.arraycopy(newArray, index, newArray, index + 1, newArray.length - index - 1);

}

// 将值放到index下标上

newArray[index] = data;

return newArray;

}

执行过程(index = 2, data = m)

c909bb91e3ed1d514102705faee397d3.png

删除数据public static String[] remove(String[] array, int index) {

// 判断参数是否合法

if (array == null || index < 0 || index >= array.length) {

throw new RuntimeException("参数不合法!");

}

// 将数据从index+1处往前移一位

System.arraycopy(array, index + 1, array, index, array.length - index - 1);

// 复制出长度-1的数组

return Arrays.copyOf(array, array.length - 1);

}

执行过程(index = 1)

985f68b68d7e521f050b1f02063d651c.png

执行结果public static void main(String[] args) {

String[] array = new String[]{"a", "b", "c", "d"};

// 在指定下标处插入数据

String[] insertArray = insert(array, 2, "m");

for (String arr : insertArray) {

System.out.print(arr);

}

System.out.println();

// 删除指定下标的数据

String[] removeArray = remove(array, 1);

for (String arr : removeArray) {

System.out.print(arr);

}

}

输出结果:abmcd

acd

方法学习

Arrays.copyOf/**

original: 原数组

newLength: 副本数组大小

*/

public static T[] copyOf(T[] original, int newLength)

复制指定数组,返回数组副本。需指定副本的大小,若副本长度超过原数组,则多余数组会填充为空;若副本长度少于原数组,则会截断原数组,并且此方法不会改变原数组。

其底层调用了System.arraycopy方法

System.arraycopy/**

src: 原数组

srcPos: 原数组起始位置

desc: 目标数组

descPos: 目标数组起始位置

length: 拷贝的长度

*/

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

将原数组中的数据拷贝到目标数组中,需指定原数组起始位置、目标数组起始位置和要拷贝的长度

参考

获取更多内容

/* * 基于数组的向量实现 */ package dsa; public class Vector_Array implements Vector { private final int N = 1024;//数组的容量 private int n = 0;//向量的实际规模 private Object[] A;//对象数组 //构造函数 public Vector_Array() { A = new Object[N]; n = 0; } //返回向量中元素数目 public int getSize() { return n; } //判断向量是否为空 public boolean isEmpty() { return (0 == n) ? true : false; } //取秩为r的元素 public Object getAtRank(int r)//O(1) throws ExceptionBoundaryViolation { if (0 > r || r >= n) throw new ExceptionBoundaryViolation("意外:秩越界"); return A[r]; } //将秩为r的元素替换为obj public Object replaceAtRank(int r, Object obj) throws ExceptionBoundaryViolation { if (0 > r || r >= n) throw new ExceptionBoundaryViolation("意外:秩越界"); Object bak = A[r]; A[r] = obj; return bak; } //插入obj,作为秩为r的元素;返回该元素 public Object insertAtRank(int r, Object obj) throws ExceptionBoundaryViolation { if (0 > r || r > n) throw new ExceptionBoundaryViolation("意外:秩越界"); if (n >= N) throw new ExceptionBoundaryViolation("意外:数组溢出"); for (int i=n; i>r; i--) A[i] = A[i-1];//后续元素顺次后移 A[r] = obj;//插入 n++;//更新当前规模 return obj; } //删除秩为r的元素 public Object removeAtRank(int r) throws ExceptionBoundaryViolation { if (0 > r || r >= n) throw new ExceptionBoundaryViolation("意外:秩越界"); Object bak = A[r]; for (int i=r; i<n; i++) A[i] = A[i+1];//后续元素顺次前移 n--;//更新当前规模 return bak; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值