数据结构之--数组(java)

线性表

提到数组,就不得不说下线性表。线性表是具有零个或多个数据元素的有限序列,并且除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表是一种最基础的数据结构,根据线性表可以构建出其它更为复杂的数据结构比如:树和图。

在数据结构中线性表有两种最基础的表现形式:数组和链表(其它的如栈、队列等都可以基于这两种基础结构来实现)。
数组是采用一些连续的空间存储数据,具备优秀的随机读取性能(时间复杂度O(1)),但为了保证联系,在插入和删除元素缺需要大量数据移动;
链表在物理存储上并非连续的,而是通过指针把一系列的非物理连续的数据空间 串联起来,从而实现逻辑上连续的线性表,链表具体优秀的随机插入和删除节点数据性能(时间复杂度O(1)),但要读取某项数据,需要遍历链表。

这使用者两种线性表构建一些复杂数据结构时,一般会根据它们不同的特点 并结合实际运用场景进行选择。本文的首先重点讲解下第一种线性--数组。

数组的特性

通过前文的描述,我们可以大概归纳出数组的下列几点特性:物理存储的连续性;查询速度快;插入和删除数据需要移动元素,性能相对低下(相对于链表)。一般在需要大量随机读取的场景下,使用数组。
 
在java中实例化一个数组,必须指定数组的容量,如:
int[] array1 = new int[6];

如果要实现容量的动态增减,可以使用jdk api中的ArrayList、Vector等,它们本质上都是基于数组实现的。所谓动态的增减数组容量,本质上是新建一个容量更大的数组,让后把老数组中的数组copy到新数组中。这个操作叫做数组的resize,也是一个比较消耗性能的操作,在具体使用时 尽量确定AarrayList的容量进行初始化,从而减少resize的次数。


使用数组创建栈

栈的特点是后进先出,使用数组可以很好的实现栈的数据结构,同时还可以具备优良的随机查询能力(数组的特性)。下面我们用数组来实现一个简单的栈:
public class MyStack<E> {
    protected Object[] elementData;
    protected int size;
    protected int elementCount;

    public MyStack(int size){
        elementData = new Object[size];
        this.size = size;
        elementCount = 0;
    }

    //添加元素
    public E push(E item){
        if(size>elementCount){
            elementData[elementCount] = item;
            elementCount++;
            return item;
        }
        return null;
    }

    //取出元素
    public E pop(){
        if(elementCount-1>=0){
            elementCount--;
            E temp = (E)elementData[elementCount];
            elementData[elementCount] = null;//帮助垃圾回收
            return temp;
        }
        return null;
    }

    public static void main(String[] args) {
        MyStack<Integer> stack = new MyStack<>(6);
        stack.push(1);
        stack.push(2);
        stack.push(3);

        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
    }
}
执行上述mian方法可以看到,这个简单的栈满足了"后进先出"的数据结构特性。在java api中自带了一个栈的是实现类Stack,它集成自Vector;Vector本身也是使用一个数组实现的。只是java自带的Stack和Vector是线程安全的实现,性能上有所消耗,多线程环境下建议使用CopyOnWriteArrayList(本质上还是基于数组实现,只是在写入数据时,需要加锁并且copy数组)。

使用数组还可以用于构建树、图,比如用于构建优先队列的二叉堆,java api的实现为PriorityQueue,这里不再一一展开。另外关于数组的问题,基本都与排序、搜索有关,后面再对常见的排序问题进行分析。



猜你喜欢

转载自blog.csdn.net/gantianxing/article/details/79850923