哈哈,距离上一次写博客已经快过去半个月了,这这这,好像有点慢啊,话不多说,开始我们的手写动态泛型数组
首先是我们自己写一个自己的动态数组类,代码如下所示:
public class Array<E> { //成员变量:数据,大小 private E[] data; private int size; //构造函数,传入数组的容量capacity public Array(int capacity) { data=(E[])new Object[capacity]; size=0; } //无参构造函数,默认capacity=10 public Array() { this(10); } //获取数组的容量 public int getCapacity() { return data.length; } //获取数组中的元素个数 public int getSize() { return this.size; } //返回数组是否为空 public boolean isEmpty() { return size==0; } //在index索引的位置插入一个新元素e public void add(int index,E e) { if(index<0||index>size) throw new IllegalArgumentException("Add faild.Require index >=0 and index <=size"); //IllegalArgumentException 非法数据异常 if(size==data.length) resize(data.length*2);//动态扩大数组容量 for(int i=size-1;i>=index;i--) { data[i+1]=data[i]; //插入的位置后的元素都应该向后移位 } data[index]=e; size++; } //向所有元素后添加一个新元素e public void addLast(E e) { add(size,e); } //在所有元素前添加一个新元素e public void addFirst(E e) { add(0,e); } //获取index索引位置的元素 public E get(int index) { if(index<0||index>=size) throw new IllegalArgumentException("Get faild.Index is illegal."); return data[index]; } //修改index索引位置的元素为e public void set(int index,E e) { if(index<0||index>=size) throw new IllegalArgumentException("Set faild.Index is illegal."); data[index]=e; } //查找数组中是否有元素e public boolean contain(E e) { for(int i=0;i<size;i++) { if(data[i].equals(e)) return true; } return false; } //查找数组中元素e所在的索引,如果不存在元素e则返回-1 public int find(E e) { for(int i=0;i<size;i++) { if(data[i].equals(e)) return i; } return -1; } //从数组中删除index位置的元素,返回删除的元素 public E remove(int index) { if(index<0||index>=size) throw new IllegalArgumentException("Remove failed.Index is illegal."); E ret =data[index]; //保存返回值 for(int i=index;i<size;i++) { data[i]=data[i+1]; //将删除元素后的每个元素向前移动,覆盖住要被删除的元素 } size--; data[size]=null; //将最后的引用设为null,否则空间无法回收 if(size==data.length/4&&data.length/2!=0)//这里是当元素数量等于容量的1/4时,进行缩容操作 resize(data.length/2); return ret; } //从数组中删除第一个元素,返回删除的元素 public E removeFirst() { return remove(0); } //从数组中删除最后一个元素,返回删除的元素 public E removeLast() { return remove(size-1); } //从数组中删除元素e public void removeElement(E e) { int index=this.find(e); if(index!=-1) remove(index); } //将数组空间的容量变为newCapacity private void resize(int newCapacity) { E[] newData= (E[])new Object[newCapacity]; for(int i=0;i<size;i++) { newData[i]=data[i]; } data=newData; //data指向newData } //重写tostring方法 @Override public String toString() { StringBuffer res=new StringBuffer(); res.append(‘[‘); for(int i=0;i<size;i++) { res.append(data[i]); if(i!=size-1) res.append(", "); } res.append(‘]‘); return res.toString(); } }
接着在写一个测试方法:
public class Main { public static void main(String[] args) { Array<Integer> arr=new Array<>(); for(int i=0;i<10;i++) arr.addLast(i); //向数组尾部添加10个元素 System.out.println(arr);//打印 System.out.println("---------------------------"); arr.add(1, 100); //向下标为1的位置添加元素100 System.out.println(arr); System.out.println("---------------------------"); arr.addFirst(-1); //向数组头部添加 System.out.println(arr); System.out.println("---------------------------"); arr.remove(2); //删除下标2的元素 System.out.println(arr); System.out.println("---------------------------"); arr.removeElement(4); //删除元素4 System.out.println(arr); System.out.println("---------------------------"); arr.removeFirst(); //删除第一个元素 System.out.println(arr); System.out.println("---------------------------"); for(int i = 0 ; i < 4 ; i ++){ arr.removeFirst(); System.out.println(arr); } } }
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] --------------------------- [0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] --------------------------- [-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] --------------------------- [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] --------------------------- [-1, 0, 1, 2, 3, 5, 6, 7, 8, 9] --------------------------- [0, 1, 2, 3, 5, 6, 7, 8, 9] --------------------------- [1, 2, 3, 5, 6, 7, 8, 9] [2, 3, 5, 6, 7, 8, 9] [3, 5, 6, 7, 8, 9] [5, 6, 7, 8, 9]
ok,这就完成了自己的动态泛型数组。
接下来分析一下时间复杂度:
//添加操作 addLast(e) O(1) addFirst(e) O(n) add(index,e) O(n/2)=O(n) //删除操作 removeLast(e) O(1) removeFirst(e) O(n) remove(index,e) O(n/2)=O(n) //修改操作 set(index,e) O(1) //查找操作 get(index) O(1) contains(e) O(n) find(e) O(n) //总结 增:O(n) 存在resize O(n) 删:O(n) 存在resize O(n) 改:已知索引O(1);未知索引O(n) 查:已知索引O(1);未知索引O(n)
ok,今天的数据结构第一篇:封装自己的动态数组就写到这了,希望可以多多关注我接下来的博文哦
有啥问题可以直接在下方评论区留言,我已经开通了微信提醒,会第一时间回复的。
对于学习,四个字概括:至死方休!
原文地址:https://www.cnblogs.com/LASloner/p/10721407.html
时间: 2024-10-29 05:45:11