【数据结构】数组简介

数组

简介

  • 数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
  • 线性表:零个或多个数据元素的有限序列。每个线性表上的数据最多只有前和后两个方向。其实除了数组,链表、队列、栈等也是线性表结构。

优缺点

优点

1、按照索引查询元素速度快;
2、能存储大量数据;
3、按照索引遍历数组方便;
4、数组定义简单,而且访问很方便;
5、可以随机访问其中的元素。

缺点

1、根据内容查找元素速度慢;
2、数组的大小一经确定不能改变,不适合动态存储;
3、数组智能存储一种类型的数据;
4、增加、删除元素效率慢;
5、未封装任何方法,所有操作都需要用户自己定义;
6、数组的空间必须是连续的,这就造成数组在内存中分配空间时必须找到一块连续的内存空间。所以数组不可能定义的太大,因为内存中不可能有那么多大的连续的内存空间,而解决这个问题的方法就是使用链表。

数组的创建

	    int a[] = new int[]{1,4,5,3,2,0,9,6,2};
        System.out.println(Arrays.toString(a));

【数据结构】数组简介_第1张图片

创建了一个长度为9的数组a,(数组以0位起始索引)并存储int类型的数字

数组的添加

【数据结构】数组简介_第2张图片

假设数组的长度为 n,将一个数据插入到数组中的第 k 个位置。为了把第 k 个 位置腾出来,给新来的数据,我们需要将第 k~n 这部分的元素都顺序地往后挪一位。

  • 如果在数组的末尾插入元素,那就不需要移动数据了,这时的时间复杂度为 O(1)。
  • 如果在数组的开头插入元素,那所有的数据都需要依次往后移动一位,所以最坏时间复杂度是 O(n)。 因为我们在每个位置插入元素的概率是一样的,所以平均情况时间复杂度为 (1+2+…n)/n=O(n)。
  • 如果数组的长度固定且有限,要继续添加元素就必须要给数组进行扩容处理。
	    int a[] = new int[]{1,4,5,3,2,0,9,6,2};
        int val = 3;//需要插入的元素
        int flag = 4;//元素插入的位置
        int cnt = 0;//用来存储a的索引
        int arr[] = new int[a.length+1];//创建新数组接收元素
        for (int i = 0; i < arr.length; i++) {
            if(i == flag){
                arr[i] = val;
                continue;
            }
            arr[i] = a[cnt];
            cnt ++;
        }
        System.out.println(Arrays.toString(arr));

数组的删除

与插入数据类似,我们要删除第 k 个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞,内存就不连续了。

  • 如果删除的元素在数组的末位,不需要对其他数据进行移动

  • 如果删除的元素在数组的首位,那所有的元素都需要一次向前移一位,所以最坏的时间复杂度是O(n)。所以平均情况时间福再度为 (1+2+…n)/n=O(n)。

    【数据结构】数组简介_第3张图片

		//删除指定位置的代码
        int a[] = new int[]{1, 4, 5, 3, 2, 0, 9, 6, 2};
        int arr[] = new int[a.length - 1];
        int flag = 4;//需要删除元素的位置
        int cnt = 0;//用来存储a的索引
        for (int i = 0; i < arr.length; i++) {
            if (i == flag) {
                cnt++;
            }
            arr[i] = a[cnt];
            cnt++;
        }
        System.out.println(Arrays.toString(arr));

数组的修改

  • 如果知道需要修改的值的索引 只需要根据索引对数组中的元素进行替换即可
int flag = 3; //修改索引为3的值
int val = 5;//需要修改的值
int a[] = new int[]{1, 4, 5, 3, 2, 0, 9, 6, 2};
a[flag] = val;
System.out.println(Arrays.toString(a));
  • 如果只知道需要修改的值,就必须遍历一遍数组,将对应的值修改为目标值
int flag = 3; //修改值为3的值
int val = 5;//需要修改成的值
int a[] = new int[]{1, 4, 5, 3, 2, 0, 9, 6, 2};
for(int i = 0 ; i < a.length; i ++){
    if(a[i] == flag){
        a[i] = val;
    }
}
System.out.println(Arrays.toString(a));

ArrayList集合类

  • ArrayList 类实现了List 接口,由ArrayList 类实现的List 集合采用数组结构保存对象。
  • 数组结构的优点是便于对集合进行快速的随机访问,如果经常需要根据索引位置访问集合中的对象,使用由 ArrayList 类实现的List集合的效率较高。数组结构的缺点是向指定索引位置插入对象和删除指定索引位置对象的速度较慢,如果经常需要向 List 集合的指定索引位置插入对象,或者删除 List 集合的指定索引位置的对象,使用由 ArrayList类实现的 List 集合的效率则较低,并且插入或删除对象的索引位置越小效率越低。原因是当向指定的索引位置插入对象时,会同时将指定索引位置及之后的所有对象相应的向后移动一位。
  • 相比于数组,ArrayList集合类可以做到动态扩容,每次存储空间不够的时候,它都会将空间自动扩容为 初始值的1.5 倍大小。

泛型

数组中除了可以保存Int Double Char 等基础类型,也可以保存对象

基本数据类型: 8种 byte char boolean int short float double long 每种基本数据类型都有一个对应的包装类

实现一个自己的数组类

package com.company.ffyc.lesson01;

import java.util.Random;

/**
 * 构建自己的数组
 */
public class MySelfArray<T> {
    private T[] data;// 数组容器
    private int size;// 实际存放元素的个数
    private int capacity;// 容积

    // 构造函数
    public MySelfArray() {
        this(100);
    }

    public MySelfArray(int capacity) {
        this.data = (T[]) new Object[capacity];
        this.size = 0;
        this.capacity = capacity;
    }

    // 获取数组中实际存放元素的个数
    public int getSize() {
        return this.size;
    }

    // 获取容量
    public int getCapacity() {
        return this.capacity;
    }

    // 判断数组是否为空
    public boolean isEmpty() {
        return this.size == 0;
    }

    // 向数组的尾部添加元素---this.size 永远指向待插入元素的位置
    public void addTail(T val) {
        this.add(this.size, val);
    }

    // 向数组的头部添加元素
    public void addHead(T val) {
        this.add(0, val);
    }

    // 向任意位置添加元素
    public void add(int index, T val) {
        if (index < 0 || index > this.size) {
            throw new IllegalArgumentException("the index is invalid!");
        }
        if (this.size == this.data.length) {
            // 进行扩容
            resize(this.data.length * 2);
        }
        for (int i = this.size; i > index; i--) {
            this.data[i] = this.data[i - 1];
        }
        this.data[index] = val;
        this.size += 1;
    }


    private void resize(int newCapacity) {
        T[] newArr = (T[]) new Object[newCapacity];
        // 将源数组中的内容复制到新数组中
        for (int i = 0; i < this.size; i++) {
            newArr[i] = this.data[i];
        }
        this.data = newArr;
        this.capacity = newCapacity;
    }

    // 获取指定位置的元素
    public T getEleByIndex(int index) {
        if (index < 0 || index >= this.size) {
            throw new IllegalArgumentException("the index is invalid!");
        }
        return this.data[index];
    }

    // 修改指定位置的元素
    public void modifyByIndex(int index, T val) {
        if (index < 0 || index >= this.size) {
            throw new IllegalArgumentException("the index is invalid!");
        }
        this.data[index] = val;
    }

    // 判断是否包含打指定的元素
    public boolean contains(T val) {
        for (int i = 0; i < this.size; i++) {
            if (this.data[i].equals(val)) {
                return true;
            }
        }
        return false;
    }

    // 根据val搜索对应的位置
    public int search(T val) {
        for (int i = 0; i < this.size; i++) {
            if (this.data[i].equals(val)) {
                return i;
            }
        }
        return -1;
    }

    // 删除元素
    public void removeEle(T val) {
        for (int i = 0; i < this.size; i++) {
            if (this.data[i].equals(val)) {
                for (int j = i; j < this.size - 1; j++) {
                    this.data[j] = this.data[j + 1];
                }
                break;
            }
        }

        this.size -= 1;
        // 进行缩容
        if (this.size == this.capacity / 2 && this.capacity / 2 > 0) {
            resize(this.capacity / 2);
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < this.size; i++) {
            sb.append(this.data[i]);
            if (i != this.size - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}

你可能感兴趣的:(数据结构与算法,数据结构,java)