目录
一、尾部插入(添加)
1.初始化
2.一个打印数组的函数
3.尾插
4.完整版
二、任意位置插入
1.流程图
2.任意插
3.完整版
三、指定数据删除
1.流程图
2. 删除(首位查找到的元素)
四、删除所有
思想
代码
五、有序数组的插入(两种方法)
思想
1.嵌套两个函数
2.嵌套一个函数
一、尾部插入(添加)
首先,时刻了解Java运行的内存图,参见Java基础06(代码运行时的内存图)-CSDN博客
如上述所见,得到一个逻辑流程,接下来我们来实现它。
1.初始化
package 数据结构;import java.util.ArrayList;
import java.util.Arrays;import org.apache.jasper.tagplugins.jstl.core.ForEach;
//尾部的位置插入
public class Test {//全局变量(写在外面)int size=0;//记录有效数组的个数int capacity=10;//数组容量double factor=1.5;//因数1.5int[] arr=new int[capacity];}
2.一个打印数组的函数
【注:】虽然Java中存在ArrayList类可以直接调用类里面的Arrays.toString()方法达到相同的数组打印效果,但是Java内的底层存在如ArrayList类本质上也是提前写好的函数,所以此处着重复现这些函数。
打印函数:
public String toString() {String res="[";for(int i=0;i<size;i++) {if(i==size-1) {res+=arr[i];//除了最后一个外,后面都跟着逗号}else {res+=arr[i]+",";}}res+="]";return res;}
3.尾插
尾插的第一步就是判断数组空间是否还有空闲;
而且String类型是不可变的,所以一旦满数组后,需要进行扩容,为了解决String类型不可变的问题,可以采用其他类型,详细可见Java基础05-CSDN博客
这里采用基础扩容的方式:
if(size==capacity) {//数组满了,扩容capacity=(int) (capacity*factor);//强制将capacity*factor转换成int类型数据int[] brr=new int[capacity];for(int i=0;i<arr.length;i++) {brr[i]=arr[i];}arr=brr;}
判断不满,或者是满了进行扩容后,就可以顺利在数组尾部插入数据。
4.完整版
public void add(int element) {if(size==capacity) {//数组满了,扩容capacity=(int) (capacity*factor);//强制将capacity*factor转换成int类型数据int[] brr=new int[capacity];for(int i=0;i<arr.length;i++) {brr[i]=arr[i];}arr=brr;}//插入数据arr[size]=element;size++;}
二、任意位置插入
1.流程图
2.任意插
任意位置插入时,不仅要考虑插入位置是否合法,还要判断是否满;判满和扩容在1.3已经给出;
判断合法性就是看插入位置是否在元素对列的包含范围内。
if(position<0||position>size) {return;}//判断数组没满if(size==capacity) {//数组满了,扩容capacity=(int) (capacity*factor);//强制将capacity*factor转换成int类型数据int[] brr=new int[capacity];for(int i=0;i<arr.length;i++) {brr[i]=arr[i];}arr=brr;}
完成上述过程后,就可以进行后移动操作(将插入位置后的数据全部后移一个位置,为插入数据留位置),防止数据产生覆盖而丢失的现象。
//有空间插入,需要将插入位置后的元素都向后移动一位,腾出空间for(int i=size-1;i>=position;i--) {arr[i+1]=arr[i];}//插入arr[position]=value;size++;//插入完成
3.完整版
//指定位置插入public void insert(int value,int position) {if(position<0||position>size) {return;}//判断数组没满if(size==capacity) {//数组满了,扩容capacity=(int) (capacity*factor);//强制将capacity*factor转换成int类型数据int[] brr=new int[capacity];for(int i=0;i<arr.length;i++) {brr[i]=arr[i];}arr=brr;}//有空间插入,需要将插入位置后的元素都向后移动一位,腾出空间for(int i=size-1;i>=position;i--) {arr[i+1]=arr[i];}//插入arr[position]=value;size++;//插入完成}
三、指定数据删除
1.流程图
删除通常用Boolean,返回删除成功或不成功。
2. 删除(首位查找到的元素)
查找就是从后向前将待删除数据覆盖的过程:
//删除第一个符合条件的数据//删除通常用Boolean,返回删除成功或不成功public boolean delFirst(int value) {//查找元素for(int j=0;j<size;j++) {if(arr[j]==value) {//删除(从目标元素后向前覆盖)for(int i=j+1;i<size;i++) {arr[i-1]=arr[i];}size--;return true;//注意return的返回}}return false;}
四、删除所有
思想
在三、的基础上:删除一项时,可以直接从前向后遍历数组去寻找这一项数据,但是这种方法只适合删除一项的情况,因为从后向前覆盖和从前向后查找很容易产生盲区,导致删除不干净的现象,为此统一-->查找时也从后向前查找。
代码
//删除所有public boolean delAll(int value) {//查找元素(从后向前删除)for(int j=size;j>0;j--) {if(arr[j]==value) {//删除(从目标元素后向前覆盖)for(int i=j+1;i<size;i++) {arr[i-1]=arr[i];}size--;}}return false;}
五、有序数组的插入(两种方法)
思想
有序函数的插入相当于是一种特殊的"任意位置插入",只是这个插入位置是要从前向后遍历得到的;特殊情况:当遍历一遍后都没有合适的位置,只能意味着这个数据的位置就该是尾部,此时有序插入进化成尾部插入。
1.嵌套两个函数
非静态函数之间可以互相引用,所以借用这种规则,可以如下:
//有序数组的插入public void sortInsert(int value) {for(int n=0;n<size;n++) {if(arr[n]>=value) {insert(value, n);return;//找到插入后就返回}}add(value);}
2.嵌套一个函数
//有序数组的插入public void sortInsert(int value) { int n; for (n = 0; n < size && arr[n] < value; n++) { // 寻找插入位置 } insert(value, n); // 直接在找到的位置插入 }