1. package cn.wllsrx.zoe.java;
  2. /**
  3. * 实现动态数组的数据结构
  4. *
  5. * @author zoe
  6. * <p>
  7. * 时间复杂度
  8. * <p>
  9. * addLast(e) O(1)
  10. * addFirst(e) O(n)
  11. * add(index,e) O(n/2)=O(n)
  12. * 添加的操作时间复杂度总的复杂度为O(n)
  13. * <p>
  14. * removeLast(e) O(1)
  15. * removeFirst(e) O(n)
  16. * remove(index,e) O(n/2)=O(n)
  17. * 删除操作时间复杂度 O(n) resize时间复杂度O(1)
  18. * <p>
  19. * set(index,e) O(1)
  20. * 修改操作复杂度 已知索引O(1) 未知索引 O(n)
  21. * <p>
  22. * get(index) O(1)
  23. * contains(e) O(n)
  24. * find(e) O(n)
  25. * 查询操作时间复杂度 已知索引O(1) 未知索引 O(n)
  26. **/
  27. public class Array<E> {
  28. private E[] data;
  29. private int size;
  30. /**
  31. * 用户传入数组长度
  32. *
  33. * @param capacity 数组长度
  34. */
  35. public Array(int capacity) {
  36. this.data = (E[]) new Object[capacity];
  37. this.size = 0;
  38. }
  39. public Array() {
  40. this(10);
  41. }
  42. /**
  43. * 获取数组中的元素个数
  44. *
  45. * @return 个数
  46. */
  47. public int getSize() {
  48. return size;
  49. }
  50. /**
  51. * 获取数组的容量
  52. *
  53. * @return 容量
  54. */
  55. public int getCapacity() {
  56. return data.length;
  57. }
  58. /**
  59. * 判断数组是否为空
  60. *
  61. * @return 结果
  62. */
  63. public boolean isEmpty() {
  64. return size == 0;
  65. }
  66. /**
  67. * 在所有元素后添加一个新元素
  68. *
  69. * @param e 新元素
  70. */
  71. public void addLast(E e) {
  72. /*if (size == data.length) {
  73. throw new IllegalArgumentException("addLast failed. array is full");
  74. }
  75. data[size] = e;
  76. size++;*/
  77. add(size, e);
  78. }
  79. /**
  80. * 在所有元素前添加一个新元素
  81. *
  82. * @param e 新元素
  83. */
  84. public void addFirst(E e) {
  85. add(0, e);
  86. }
  87. /**
  88. * 在传入索引的位置插入新元素
  89. *
  90. * @param index 索引
  91. * @param e 元素
  92. */
  93. public void add(int index, E e) {
  94. //判断要插入的索引位置是否大于0
  95. if (index < 0 || index > size) {
  96. throw new IllegalArgumentException("add failed. array is full");
  97. }
  98. if (size == data.length) {
  99. //数组内存扩容两倍
  100. resize(2 * data.length);
  101. }
  102. //从最后一个下标开始,将下标大于index的元素向后挪,直到index索引位置,将e插入
  103. for (int i = size - 1; i >= index; i--) {
  104. //给后一个位置的元素赋上前一个元素的值
  105. data[i + 1] = data[i];
  106. }
  107. data[index] = e;
  108. size++;
  109. }
  110. private void resize(int newCapacity) {
  111. E[] newData = (E[]) new Object[newCapacity];
  112. for (int i = 0; i < size; i++) {
  113. newData[i] = data[i];
  114. }
  115. data = newData;
  116. }
  117. /**
  118. * 获取index索引位置的元素
  119. *
  120. * @param index 索引位置
  121. * @return 元素
  122. */
  123. E get(int index) {
  124. if (index < 0 || index >= size) {
  125. throw new IllegalArgumentException("get failed. index is illegal");
  126. }
  127. return data[index];
  128. }
  129. /**
  130. * 修改index索引位置的元素为e
  131. *
  132. * @param index 索引
  133. * @param e 新元素
  134. */
  135. void set(int index, E e) {
  136. if (index < 0 || index >= size) {
  137. throw new IllegalArgumentException("get failed. index is illegal");
  138. }
  139. data[index] = e;
  140. }
  141. /**
  142. * 数组中是否存在元素e
  143. *
  144. * @param e 元素
  145. * @return 存在true
  146. */
  147. public boolean contains(E e) {
  148. for (int i = 0; i < size; i++) {
  149. if (data[i].equals(e)) {
  150. return true;
  151. }
  152. }
  153. return false;
  154. }
  155. /**
  156. * 查询元素的索引
  157. *
  158. * @param e 元素
  159. * @return 存在返回索引, 不存在返回-1
  160. */
  161. public int find(E e) {
  162. for (int i = 0; i < size; i++) {
  163. if (data[i].equals(e)) {
  164. return i;
  165. }
  166. }
  167. return -1;
  168. }
  169. /**
  170. * 删除当前索引位置的元素,返回删除元素
  171. *
  172. * @param index 索引
  173. * @return 删除元素
  174. */
  175. public E remove(int index) {
  176. if (index < 0 || index >= size) {
  177. throw new IllegalArgumentException("get failed. index is illegal");
  178. }
  179. E ret = data[index];
  180. for (int i = index + 1; i < size; i++) {
  181. data[i - 1] = data[i];
  182. }
  183. size--;
  184. //data[size] = null;
  185. //动态缩容数组长度 当实际数组长度是数组的四分之一时,将数组长度减半,防止复杂度震荡
  186. if (size == data.length / 4 && data.length / 2 != 0) {
  187. resize(data.length / 2);
  188. }
  189. return ret;
  190. }
  191. /**
  192. * 删除数组中的第一个元素
  193. *
  194. * @return 被删除的元素
  195. */
  196. public E removeFirst() {
  197. return remove(0);
  198. }
  199. /**
  200. * 删除数组中最后一个元素
  201. *
  202. * @return 被删除得元素
  203. */
  204. public E removeLast() {
  205. return remove(size - 1);
  206. }
  207. /**
  208. * 删除元素e
  209. *
  210. * @param e 元素
  211. */
  212. public void removeElement(E e) {
  213. int index = find(e);
  214. if (index != -1) {
  215. remove(index);
  216. }
  217. }
  218. @Override
  219. public String toString() {
  220. StringBuilder builder = new StringBuilder();
  221. builder.append(String.format("Array: size = %d,capacity = %d\n", size, data.length));
  222. builder.append("[");
  223. for (int i = 0; i < size; i++) {
  224. builder.append(data[i]);
  225. if (i != size - 1) {
  226. builder.append(",");
  227. }
  228. }
  229. builder.append("]");
  230. return builder.toString();
  231. }
  232. public static void main(String[] args) {
  233. Array<Integer> array = new Array<>(20);
  234. for (int i = 0; i < 10; i++) {
  235. array.addLast(i);
  236. }
  237. System.out.println(array);
  238. array.add(1, 54);
  239. System.out.println(array);
  240. }
  241. }

项目demo