Java实现动态数组(数据结构与算法)
Posted 程序员小贤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实现动态数组(数据结构与算法)相关的知识,希望对你有一定的参考价值。
前言:为什么需要动态数组?
1,我们之前用的数组最大的问题就在于数组长度定长,一旦一个数组在定义时确定长度之后,使用过程中无法修改这个长度。
2,Java中提供的数组都是静态数组int[] char[] long[](定义之后没法改变长度) 所以需要我们自己定义一个类,拓展基础数组的功能。
一、什么是动态数组
Java中提供的数组都是静态数组,即在一个数组定义时确定长度后,使用过程中无法修改此长度。 动态数组就是在普通数组上,增加了一个可以根据元素的个数动态调整数组大小的功能。
二、动态数组的实现
创建一个MyArrayList类 为可变类型Object参数 size为元素的数量 elements为所有的元素 DEFAULT_CAPACITY为默认组的数量 并且初始化构造方法
package com.szx; @SuppressWarnings("unchecked") public class MyArrayList<E> /** * 元素的数量 */ private int size; /** * 所有的元素 */ private E[] elements; /** * 默认数组数量 */ private static final int DEFAULT_CAPACITY=2; /** * 返回-1索引不存在 */ private static final int ELEMENT_NOT_FOUND=-1; public MyArrayList(int capaticy) //如果新的数组数量小于默认的数组 那么就用新的 ,默认为2 capaticy = (capaticy<DEFAULT_CAPACITY)?DEFAULT_CAPACITY:capaticy; elements = (E[]) new Object[capaticy]; public MyArrayList() this(DEFAULT_CAPACITY);
接口的设计
◼ int size(); // 元素的数量
◼ boolean isEmpty(); // 是否为空
◼ boolean contains(E element); // 是否包含某个元素
◼ void add(E element); // 添加元素到最后面
◼ E get(int index); // 返回index位置对应的元素
◼ E set(int index, E element); // 设置index位置的元素
◼ void add(int index, E element); // 往index位置添加元素
◼ E remove(int index); // 删除index位置对应的元素
◼ int indexOf(E element); // 查看元素的位置
◼ void clear(); // 清除所有元素
1添加元素-add(E element)
0 1 2 3 4 5 6
element |
0 1 2 3 4 5 6
10 | 20 | 30 | 40 | 50 | element |
当size=5时
核心代码:elements[size] = elemenet;
size++;
package com.szx; @SuppressWarnings("unchecked") public class MyArrayList<E> /** * 元素的数量 */ private int size; /** * 所有的元素 */ private E[] elements; /** * 默认数组数量 */ private static final int DEFAULT_CAPACITY=2; /** * 返回-1索引不存在 */ private static final int ELEMENT_NOT_FOUND=-1; public MyArrayList(int capaticy) //如果新的数组数量小于默认的数组 那么就用新的 ,默认为2 capaticy = (capaticy<DEFAULT_CAPACITY)?DEFAULT_CAPACITY:capaticy; elements = (E[]) new Object[capaticy]; public MyArrayList() this(DEFAULT_CAPACITY); /** * 元素的数量 * @return */ public int size() return size; /** * 添加元素到尾部 * @param element */ public void add(E element) add(size,element); /** * 往index位置添加元素 * @param index * @param element */ public void add(int index,E element) if(index <0||index>size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); //ensureCapacity(size+1); for (int i = size-1; i >=index; i--) elements[i+1] = elements[i]; //原来的位置存放新添加的元素 elements[index] = element; size++; @Override public String toString() StringBuffer string = new StringBuffer(); string.append("size=").append(size).append("["); for (int i = 0; i < size; i++) if(i!=0)string.append(","); string.append(elements[i]); string.append("]"); return string.toString();
测试结果:
2:数组动态扩容 经过上面测试.我们会发现数组可以正常添加但默认数量是2 超过两个就会出事:
实现动态扩容: ensureCapacity方法,在添加元素前进行调用
/** * 往index位置添加元素 * @param index * @param element */ public void add(int index,E element) if(index <0||index>size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); ensureCapacity(size+1); for (int i = size-1; i >=index; i--) elements[i+1] = elements[i]; //原来的位置存放新添加的元素 elements[index] = element; size++; /** * 保证要有capacity的容量 * @param capacity */ private void ensureCapacity(int capacity) int oldCpacity = elements.length; if(oldCpacity >=capacity) return; //int newCapacity = oldCpacity +oldCpacity*1.5; //新的容量为旧容量的1.5倍,当然也可以自己调整, //使用位运算提高效率 int newCapacity = oldCpacity +(oldCpacity>>1); E[] newElements = (E[]) new Object[newCapacity]; for (int i = 0; i < size; i++) newElements[i] = elements[i]; //替换之前的数组 elements = newElements; System.out.println(oldCpacity + "扩容为:"+newCapacity);
测试结果:
3:删除元素-remove(int index)
/** * 删除index位置对应的元素 * @param index * @return */ public E remove(int index) if(index <0||index>=size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); E old = elements[index]; for (int i = index+1; i <=size-1; i++) elements[i-1] = elements[i]; size--; elements[size] = null; return old;
4:根据idex查询对应的元素
/** * 返回index位置对应的元素 * @param index * @return */ public E get(int index) if(index <0||index>=size) System.out.println("下标越界,该数组中不存在"); throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); return elements[index];
5:设置index的元素(元素的修改)
/** * 设置index位置的元素 * @param index * @param element * @return */ public E set(int index,E element) if(index <0||index>=size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); E old = elements[index]; elements[index] = element; return old;
进行测试:
完整代码:
package com.szx; @SuppressWarnings("unchecked") public class MyArrayList<E> /** * 元素的数量 */ private int size; /** * 所有的元素 */ private E[] elements; /** * 默认数组数量 */ private static final int DEFAULT_CAPACITY=2; /** * 返回-1索引不存在 */ private static final int ELEMENT_NOT_FOUND=-1; public MyArrayList(int capaticy) //如果新的数组数量小于默认的数组 那么就用新的 ,默认为2 capaticy = (capaticy<DEFAULT_CAPACITY)?DEFAULT_CAPACITY:capaticy; elements = (E[]) new Object[capaticy]; public MyArrayList() this(DEFAULT_CAPACITY); /** * 元素的数量 * @return */ public int size() return size; /** * 添加元素到尾部 * @param element */ public void add(E element) add(size,element); /** * 往index位置添加元素 * @param index * @param element */ public void add(int index,E element) if(index <0||index>size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); ensureCapacity(size+1); for (int i = size-1; i >=index; i--) elements[i+1] = elements[i]; //原来的位置存放新添加的元素 elements[index] = element; size++; /** * 清除所有元素 */ public void clear() // if(size<=100) // size = 0; // else // // elements =null; // for (int i = 0; i < size; i++) elements[i] = null; size = 0; /** * 是否为空 * @return */ public boolean isEmpty() // if(size==0) // return true; // else // return false; // // return size==0; /** * 是否包含某个元素 * @param element * @return */ public boolean contains(E element) return indexOf(element)!=ELEMENT_NOT_FOUND; /** * 返回index位置对应的元素 * @param index * @return */ public E get(int index) if(index <0||index>=size) System.out.println("下标越界,该数组中不存在"); throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); return elements[index]; /** * 设置index位置的元素 * @param index * @param element * @return */ public E set(int index,E element) if(index <0||index>=size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); E old = elements[index]; elements[index] = element; return old; /** * 删除index位置对应的元素 * @param index * @return */ public E remove(int index) if(index <0||index>=size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); E old = elements[index]; for (int i = index+1; i <=size-1; i++) elements[i-1] = elements[i]; size--; elements[size] = null; return old; /** * 查看元素的位置 * @param element * @return */ public int indexOf(E element) if(element ==null) for (int i = 0; i < size; i++) if(elements[i]== null) return i; else for (int i = 0; i < size; i++) if(element.equals(elements[i])) return i; return -1; @Override public String toString() StringBuffer string = new StringBuffer(); string.append("size=").append(size).append("["); for (int i = 0; i < size; i++) if(i!=0)string.append(","); string.append(elements[i]); string.append("]"); return string.toString(); /** * 保证要有capacity的容量 * @param capacity */ private void ensureCapacity(int capacity) int oldCpacity = elements.length; if(oldCpacity >=capacity) return; //int newCapacity = oldCpacity +oldCpacity*1.5; //新的容量为旧容量的1.5倍,当然也可以自己调整, //使用位运算提高效率 int newCapacity = oldCpacity +(oldCpacity>>1); E[] newElements = (E[]) new Object[newCapacity]; for (int i = 0; i < size; i++) newElements[i] = elements[i]; //替换之前的数组 elements = newElements; System.out.println(oldCpacity + "扩容为:"+newCapacity);
测试代码:
package com.szx; public class Main public static void main(String[] args) MyArrayList<Integer> list1 = new MyArrayList(); list1.add(11); list1.add(22); list1.add(33); list1.add(44); System.out.println(list1.toString()); list1.remove(2); System.out.println("删除后"); System.out.println(list1.toString()); System.out.println("修改:"); list1.set(0,66); System.out.println(list1.toString());
以上是关于Java实现动态数组(数据结构与算法)的主要内容,如果未能解决你的问题,请参考以下文章
『数据结构与算法』链表(单链表双链表环形链表):原理与Java实现
买什么数据结构与算法,这里有:动态图解十大经典排序算法(含JAVA代码实现)