1. 数组数据结构的封装
1 /** 2 * @author 阿遠 3 * Date: 2019/1/13 4 * Time: 19:29 5 */ 6 // 数组操作接口的实现 7 public class Array<E> { 8 9 private E[] data; 10 private int size; // 数组中实际元素数量 11 12 // 构造函数,传入数组的容量capacity构造Array 13 public Array(int capacity) { 14 data = (E[]) new Object[capacity]; 15 size = 0; 16 } 17 // 默认构造函数,默认数组的容量capacity=10 18 public Array() { 19 this(10); 20 } 21 // 获取数组中的容量 22 public int getCapacity() { 23 return data.length; 24 } 25 //获取数组的元素个数 26 public int getSize() { 27 return size; 28 } 29 // 判断数组是否为空 30 public boolean isEmpty() { 31 return size == 0; 32 } 33 // 向所有元素后添加一个新元素 34 public void addLast(E e) { 35 // if (size == data.length){ 36 // throw new IllegalArgumentException("addLast failed!Array is full"); 37 // } 38 // data[size] = e; 39 // size++; 40 // 复用add 41 add(size, e); 42 } 43 //在所有元素前添加新元素 44 public void addFirst(E e) { 45 add(0, e); 46 } 47 // 在index个位置插入一个新元素,扩容成动态数组,此处我们扩容成原来的2倍,在ArrayList中为1.5倍 48 public void add(int index, E e) { 49 50 if (index < 0 || index > size) { 51 throw new IllegalArgumentException("Add failed!Index required >=0 and <size"); 52 } 53 if (size == data.length){ 54 resize(2 * data.length); 55 } 56 for (int i = size-1; i >= index; i--){ 57 data[i+1] = data[i]; 58 } 59 data[index] = e; 60 size ++; 61 } 62 // 给数组扩容或者缩容 63 private void resize(int newCapacity) { 64 E[] newData = (E[]) new Object[newCapacity]; 65 for (int i = 0; i < size; i++) { 66 newData[i] = data[i]; 67 } 68 data = newData; 69 } 70 // 获取index索引位置的元素 71 public E get(int index) { 72 if (index < 0 || index > size) { 73 throw new IllegalArgumentException("Get failed!Index is illegal."); 74 } 75 return data[index]; 76 } 77 //修改index元素索引位置的元素为e 78 public void set(int index, E e) { 79 if (index < 0 || index > size) { 80 throw new IllegalArgumentException("Set failed!Index is illegal."); 81 } 82 data[index] = e; 83 } 84 85 @Override 86 public String toString() { 87 StringBuilder res = new StringBuilder(); 88 res.append(String.format("Array: size = %d, capacity = %d ", size, data.length)); 89 res.append("["); 90 for (int i = 0; i < size; i++) { 91 res.append(data[i]); 92 if (i != size-1) 93 res.append(", "); 94 } 95 res.append("]"); 96 return res.toString(); 97 } 98 99 // 查找数组中是否存在元素e 100 public boolean contains(E e) { 101 for (int i= 0; i < size; i++) { 102 if (data[i] == e) 103 return true; 104 } 105 return false; 106 } 107 // 查找数组中元素e所在的索引,如果不存在元素e,则返回-1 108 public int find(E e) { 109 for (int i = 0; i < size; i++) { 110 if (data[i] == e) 111 return i; 112 } 113 return -1; 114 } 115 // 从数组中删除元素,返回删除的元素 116 public E remove(int index) { 117 if (index < 0 || index >= size) { 118 throw new IllegalArgumentException("Remove failed!Index is illegal."); 119 } 120 E ret = data[index]; 121 for (int i = index + 1; i < size; i++) { 122 data[i-1] = data[i]; 123 } 124 size --; 125 data[size] = null; // loitering objects != memory leak 126 if (size == data.length/4 && data.length/2 != 0) { 127 resize(data.length/2); 128 } 129 return ret; 130 } 131 // 从数组中删除第一个元素 132 public E removeFirst() { 133 return remove(0); 134 } 135 // 从元素中删除最后一个元素 136 public E removeLast() { 137 return remove(size-1); 138 } 139 // 从数组中删除元素e 140 public void removeElement(E e) { 141 int index = find(e); 142 if (index != -1) { 143 remove(index); 144 } 145 } 146 }
2. 数组数据结构的测试
1 public class Main { 2 3 public static void main(String[] args) { 4 5 Array<Integer> array = new Array<Integer>(); 6 for (int i = 0; i < 10; i++) { 7 array.addLast(i); 8 } 9 System.out.println(array); 10 System.out.println("在数组索引1处插入:200。此时数组会扩容为原来的2倍。"); 11 array.add(1,200); 12 System.out.println(array); 13 System.out.println("在数组最后插入:1"); 14 array.addLast(1); 15 System.out.println(array); 16 System.out.println("在数组开头插入:-1"); 17 array.addFirst(-1); 18 System.out.println(array); 19 System.out.println("移除数组开头处的元素。"); 20 array.removeFirst(); 21 System.out.println("移除数组最后的元素。"); 22 array.removeLast(); 23 System.out.println(array); 24 System.out.println("移除数组索引1处的元素。此时数组会缩容为原来的1/2倍。"); 25 array.remove(1); 26 System.out.println(array); 27 System.out.println("数组中是否包含元素:8。返回:true"); 28 System.out.println(array.contains(8)); 29 System.out.println("查询元素8所在位置的索引。返回:8"); 30 System.out.println(array.find(8)); 31 System.out.println("查询索引位置为8的元素。返回:8"); 32 System.out.println(array.get(8)); 33 } 34 }
3. 测试结果
Array: size = 10, capacity = 10 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 在数组索引1处插入:200。此时数组会扩容为原来的2倍。 Array: size = 11, capacity = 20 [0, 200, 1, 2, 3, 4, 5, 6, 7, 8, 9] 在数组最后插入:1 Array: size = 12, capacity = 20 [0, 200, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1] 在数组开头插入:-1 Array: size = 13, capacity = 20 [-1, 0, 200, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1] 移除数组开头处的元素。 移除数组最后的元素。 Array: size = 11, capacity = 20 [0, 200, 1, 2, 3, 4, 5, 6, 7, 8, 9] 移除数组索引1处的元素。此时数组会缩容为原来的1/2倍。 Array: size = 10, capacity = 10 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 数组中是否包含元素:8。返回:true true 查询元素8所在位置的索引。返回:8 8 查询索引位置为8的元素。返回:8 8
时间复杂度:常数阶O(1),对数阶O(log2n),线性阶O(n),线性对数阶O(nlog2n),平方阶O(n^2),立方阶O(n^3),指数阶O(2^n)