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) {

    }
}

 

posted @ 2020-05-22 00:58  大碗炸酱面  阅读(174)  评论(0编辑  收藏  举报