2.数据结构-动态数组
什么是数据结构?
数据结构是计算机存储,组织数据的方式,常见的数据结构:
线性结构:
- 线性表(数组,链表)
- 栈,队列
- 哈希表
树形结构:
- 二叉树
- AVL树
- 红黑树
- B树
- 堆
- Trie
- 哈夫曼树
- 并查集
图形结构:
- 邻接矩阵
- 邻接表
线性表是具有n个相同类型元素的有限序列(n>=0)
- a1是首节点,an是尾结点
- a1是a2的前驱
- a2是a1的后继
数组(Array)
数组是一种顺序存储的线性表,所有元素的内存地址是连续的
在很多编程语言中,数组都有个致命的缺点:无法动态修改容量,实际开发中,我们更希望数组的容量是可以动态改变的
动态数组的实现
package zh.algorithm.array; public class DynamicArray { private int size;// 元素的个数 private int[] elements;// 存放所有的元素 private static final int DEFAULT_CAPACITY = 1; private static final int ELEMENT_NOTFOUND = -1; private void outOfBounds(int index) { throw new IndexOutOfBoundsException("Index:" + index + ",Size:" + size); } private void rangeCheck(int index) { if (index < 0 || index >= size) { outOfBounds(index); } } private void rangeCheckForAdd(int index) { if (index < 0 || index > size) { outOfBounds(index); } } // 含参构造函数,根据传入的capacity,来创建数组 public DynamicArray(int capacity) { // 如果传入参数小于10,则修改为默认值 capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity; elements = new int[capacity]; } // 无参构造函数,如果没有指定,数组默认容量为10 public DynamicArray() { // elements = new int[DEFAULT_CAPACITY];构造函数之间调用通过this this(DEFAULT_CAPACITY); } //动态扩容 private void ensureCapacity(int capacity) { int oldCapacity = elements.length; if (oldCapacity > capacity) return; //扩容1.5倍 int newCapacity = (int) Math.round(oldCapacity * 1.5); //创建一个容量为旧容量1.5倍的新数组 int[] newElements = new int[newCapacity]; //把旧数组的元素拷贝到新元素 for (int i = 0; i < size; i++) { newElements[i] = elements[i]; } //释放旧的elements elements = newElements; } /* * 动态数组方法 */ public int size() { // 返回数组元素的个数 return size; } public boolean isEmpty() { // 判断数组是否为空 return size == 0; } public int set(int index, int element) { // 在指定索引位置插入一个新元素,并且返回旧元素 // 判断索引是否越界 rangeCheck(index); int old_element = elements[index]; elements[index] = element; return old_element; } public int get(int index) { // 通过索引查询元素 rangeCheck(index); return elements[index]; } public int indexOf(int element) { //通过元素查索引 for(int i = 0;i<size;i++) { if(elements[i]==element) return i; } return ELEMENT_NOTFOUND; } public boolean contains(int element) { //判断元素是否存在 return indexOf(element) != ELEMENT_NOTFOUND; } public void clear() { //将元素个数设为0,使原先的数组不能使用,如需添加元素,直接覆盖原来数组,避免销毁再创建,节省性能 size =0; } public void add(int element) { //添加元素到尾部 //elements[size]= element; //size++; add(size,element); } public void add(int index,int element) { //重载,在指定位置添加一个元素 rangeCheckForAdd(index); ensureCapacity(size+1); for (int i = size-1; i >=index; i--) { elements[i+1] = elements[i]; } elements[index] = element; size++; } public int remove(int index) { //删除指定的元素 rangeCheck(index); int old_element = elements[index]; for (int i = index+1; i < size; i++) { elements[i-1] = elements[i]; } size--; return old_element; } @Override public String toString() { StringBuilder string = new StringBuilder(); string.append("size=").append(size).append(",["); for (int i = 0; i < size; i++) { if (i!=0) { string.append(", "); } string.append(elements[i]); // if(i != size-1) { // string.append(", "); // } } string.append("]"); return string.toString(); } public static void main(String[] args) { } }