数据结构-数组| 8月更文挑战

240 阅读3分钟

数据结构

计算机中存储、组织数据的方式
数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素集合。
它包含三方面的内容,逻辑关系、存储关系及操作。
不同种类的数据结构适合于不同种类的应用,而部分甚至专门用于特定的作业任务。
例如,计算机网络依赖于路由表运作,B 树高度适用于数据库的封装。

常见数据结构

线性结构

线性结构指的是数据元素之间存在着“一对一”的线性关系的数据结构

数组(Array)、队列(Queue)、链表(Linked List)、栈(Stack)

非线性结构

非线性结构中各个数据元素不再保持在一个线性序列中,每个数据元素可能与
零个或者多个其他数据元素发生联系。根据关系的不同,可分为层次结构和群结构。

堆(Heap)、散列表(Hash table)、树(Tree)、图(Graph)

数组

特征

  1. 最简单、最常用的结构。
  2. 线性结构,所以内存空间是连续的
  3. 存储有限个具有相同类型的数据

优点

内存空间连续,所以存在以下优点

  1. 根据索引进行查找、修改时效率高
  2. 按照索引遍历数组方便

缺点

也因为内存空间的连续,所以也存在一些缺点

  1. 在数组非结尾位置进行插入、删除操作时,导致后面的元素被迫移动,效率低
  2. 内存空间固定,无法自动扩容
  3. 只能存储同一种类型的数据

手撸代码

添加

头部插入

public static void main(String[] args) {
    String[] array = new String[3];
    headAdd(array, "hello1");
    headAdd(array, "hello2");
    headAdd(array, "hello3");
    headAdd(array, "hello4");
    for (String i : array) {
        System.out.print(i + " ");  
    }
    // 添加:hello4,数组空间已满!
    // hello3 hello2 hello1 
}

public static void headAdd(String[] array, String str) {
    int index = array.length;
    if (null != array[index-1]) {
        System.out.println("添加:" + str + ",数组空间已满!");
    }
    for (int i = index - 2; i > 0; i--) {
        String arr = array[i];
        if (arr != null) {
            array[i+1] = arr;
        }
    }
    array[0] = str;
}

尾部插入

public static void main(String[] args) {
    String[] array = new String[3];
    tailAdd(array, "hello1");
    tailAdd(array, "hello2");
    tailAdd(array, "hello3");
    tailAdd(array, "hello4");
    for (String i : array) {
        System.out.print(i + " ");
    }
    // 添加:hello4,数组空间已满!
    // hello1 hello2 hello3 
}

public static void tailAdd(String[] array, String str) {
    int index = array.length;
    if (null != array[index-1]) {
        System.out.println("添加:" + str + ",数组空间已满!");
        return;
    }
    for (int i = 0; i < index; i++) {
        String arr = array[i];
        if (arr == null) {
            array[i] = str;
            break;
        }
    }
}

指定位置插入

public static void main(String[] args) {
    String[] array = new String[3];
    appointAdd(array, "hello1", 1);
    appointAdd(array, "hello2", 1);
    for (String i : array) {
        System.out.print(i + " ");
    }
    // null hello2 hello1 
}

public static void appointAdd(String[] array, String str, int x) {
    int index = array.length;
    if (x >= index) {
        System.out.println("下标越界!");
        return;
    }
    if (null != array[index-1]) {
        System.out.println("添加:" + str + ",数组空间已满!");
        return;
    }
    for (int i = index - 1; i >= 0; i--) {
        if (array[i] != null) {
            array[i+1] = array[i];
        }
        if (i == x) {
            array[i] = str;
            break;
        }
    }
}

修改

public static void main(String[] args) {
    String[] array = new String[3];
    appointAdd(array, "hello1", 1);
    update(array, "hello2", 1);
    for (String i : array) {
        System.out.print(i + " ");
    }
    // null hello2 null
}

public static void update(String[] array, String str, int x) {
    int index = array.length;
    if (x >= index) {
        System.out.println("下标越界!");
        return;
    }
    array[x] = str;
}

删除

public static void main(String[] args) {
    String[] array = new String[3];
    appointAdd(array, "hello1", 1);
    appointAdd(array, "hello2", 1);
    update(array, "hello3", 0);
    delete(array, 0);
    for (String i : array) {
        System.out.print(i + " ");
    }
    // hello2 hello1 null
}

public static void delete(String[] array, int x) {
    int index = array.length;
    if (x >= index) {
        System.out.println("下标越界!");
        return;
    }
    for (int i = x; i < index; i++) {
        if (i < index - 1) {
            array[i] = array[i+1];
            array[i+1] = null;
        }
    }
}

查找

public static void main(String[] args) {
    String[] array = new String[3];
    appointAdd(array, "hello1", 1);
    appointAdd(array, "hello2", 1);
    update(array, "hello3", 0);
    get(array, 1);
    for (String i : array) {
        System.out.print(i + " ");
    }
    // 查询数据为:hello2
    // hello3 hello2 hello1
}

public static void get(String[] array, int x) {
    int index = array.length;
    if (x >= index) {
        System.out.println("下标越界!");
        return;
    }
    System.out.println("查询数据为:" + array[x]);
}

总结

根据上面代码可以看出
效率最高的是修改、查询,直接根据索引位置就可以达到预期效果;
其次是尾部插入,需要循环找到为空的最后位置;
最后是头部插入、指定位置插入、删除;因为还需要移动其他元素位置;

适用场景

频繁查询,对存储空间要求不大,很少增加和删除的情况。