数据结构 -- 数组(Array)

1、定义

数组(Array)是一种线性表数据结构 ,用于 存储 一组具有相同类型的数据元素。 数组是一种有序的集合,通过编号来唯一标识每个元素,即所谓的下标。

2、特性

  • 线性表:线性表是一种数据元素顺序排列、类型相同的数据结构,每个元素最多只有前驱和后继两个相邻元素。数组正是线性表的一种典型实现,此外,栈、队列、链表等也属于线性表结构。
  • 连续的内存空间:线性表有「顺序存储」和「链式存储」两种方式。顺序存储结构要求内存空间连续,相邻元素在物理内存中紧挨着。数组采用的正是顺序存储结构,且所有元素类型一致。

3、特点

  • 类型统一:数组中的所有元素都必须是相同的数据类型。
  • 固定大小:一旦创建了数组,其大小就固定不变。
  • 连续存储:数组的所有元素在内存中是连续存放的。
  • 随机访问:可以直接通过索引访问任意位置的元素,时间复杂度为O(1)。

4、操作方法

数组支持多种基本操作,包括初始化、访问、插入、删除等

4.1 初始化

声明数组

复制代码
// 静态初始化
int[] arr1 = {1, 2, 3, 4, 5};
String[] arr2 = {"Java", "Python", "C++"};

// 动态初始化
int[] arr3 = new int[5];
arr3[0] = 10;
arr3[1] = 20;

4.2 访问

通过下标索引进行访问

复制代码
 // 2. 访问元素
        System.out.println("\n=== 访问操作 ===");
        System.out.println("第一个元素: " + arr[0]);  // 索引0
        System.out.println("最后一个元素: " + arr[arr.length - 1]);  // 索引 length-1

4.3 修改

通过下标直接进行修改即可

复制代码
 // 3. 修改元素
        System.out.println("\n=== 修改操作 ===");
        arr[2] = 100;  // 修改第三个元素
        System.out.println("修改后: " + Arrays.toString(arr));

4.4 遍历

使用length表示数组的长度

复制代码
 // 4. 遍历数组
        System.out.println("\n=== 遍历数组 ===");
        System.out.print("for循环: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        
        System.out.print("\n增强for循环: ");
        for (int num : arr) {
            System.out.print(num + " ");
        }

4.5 查找

通过下表进行查找

复制代码
// 5. 查找元素
        System.out.println("\n\n=== 查找操作 ===");
        int target = 40;
        int index = -1;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                index = i;
                break;
            }
        }
        System.out.println(target + " 的索引位置: " + (index != -1 ? index : "未找到"));

4.6 确定数组长度与类型

复制代码
 // 6. 获取数组信息
        System.out.println("\n=== 数组信息 ===");
        System.out.println("数组长度: " + arr.length);
        System.out.println("数组类型: " + arr.getClass().getSimpleName());

5、算法

5.1 插入

复制代码
public class ArrayInsert {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 0, 0, 0};  // 预留空间
        int size = 5;  // 当前有效元素个数
        
        System.out.println("插入前: " + Arrays.toString(arr));
        
        // 在索引2处插入100
        int insertIndex = 2;
        int insertValue = 100;
        
        // 从后往前移动元素
        for (int i = size; i > insertIndex; i--) {
            arr[i] = arr[i - 1];
        }
        
        // 插入新元素
        arr[insertIndex] = insertValue;
        size++;  // 有效元素增加
        
        System.out.println("插入后: " + Arrays.toString(arr));
    }
}

5.2 删除

复制代码
public class ArrayDelete {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int size = 5;
        
        System.out.println("删除前: " + Arrays.toString(arr));
        
        // 删除索引2处的元素
        int deleteIndex = 2;
        
        // 从删除位置开始,向前移动元素
        for (int i = deleteIndex; i < size - 1; i++) {
            arr[i] = arr[i + 1];
        }
        
        // 最后一个元素置0(可选)
        arr[size - 1] = 0;
        size--;  // 有效元素减少
        
        System.out.println("删除后: " + Arrays.toString(Arrays.copyOf(arr, size)));
    }
}

5.3 反转数组

复制代码
public class ArrayReverse {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        System.out.println("反转前: " + Arrays.toString(arr));
        
        // 双指针法反转
        int left = 0;
        int right = arr.length - 1;
        
        while (left < right) {
            // 交换元素
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            
            left++;
            right--;
        }
        
        System.out.println("反转后: " + Arrays.toString(arr));
    }
}

5.4 查找最大最小值

复制代码
public class ArrayMinMax {
    public static void main(String[] args) {
        int[] arr = {3, 5, 1, 8, 2, 7};
        
        int min = arr[0];
        int max = arr[0];
        
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] < min) {
                min = arr[i];
            }
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        
        System.out.println("数组: " + Arrays.toString(arr));
        System.out.println("最小值: " + min);
        System.out.println("最大值: " + max);
    }
}

6、二维数组

复制代码
public class TwoDArray {
    public static void main(String[] args) {
        // 1. 声明和初始化
        int[][] matrix1 = new int[3][4];  // 3行4列
        int[][] matrix2 = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        
        // 2. 访问元素
        System.out.println("matrix2[1][2] = " + matrix2[1][2]);  // 6
        
        // 3. 遍历二维数组
        System.out.println("\n遍历二维数组:");
        for (int i = 0; i < matrix2.length; i++) {  // 行
            for (int j = 0; j < matrix2[i].length; j++) {  // 列
                System.out.print(matrix2[i][j] + "\t");
            }
            System.out.println();
        }
        
        // 4. 获取数组信息
        System.out.println("\n行数: " + matrix2.length);
        System.out.println("列数: " + matrix2[0].length);
    }
}

7、矩阵转置

复制代码
public class MatrixTranspose {
    public static void main(String[] args) {
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6}
        };
        
        System.out.println("原始矩阵:");
        printMatrix(matrix);
        
        // 转置
        int rows = matrix.length;
        int cols = matrix[0].length;
        int[][] transpose = new int[cols][rows];
        
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                transpose[j][i] = matrix[i][j];
            }
        }
        
        System.out.println("转置矩阵:");
        printMatrix(transpose);
    }
    
    static void printMatrix(int[][] matrix) {
        for (int[] row : matrix) {
            for (int num : row) {
                System.out.print(num + "\t");
            }
            System.out.println();
        }
    }
}

8、常用方法

复制代码
import java.util.Arrays;

public class ArraysUtility {
    public static void main(String[] args) {
        int[] arr = {5, 3, 8, 1, 9, 2};
        
        // 1. 排序
        Arrays.sort(arr);
        System.out.println("排序后: " + Arrays.toString(arr));
        
        // 2. 二分查找(必须先排序)
        int index = Arrays.binarySearch(arr, 8);
        System.out.println("8的索引: " + index);
        
        // 3. 填充数组
        int[] arr2 = new int[5];
        Arrays.fill(arr2, 7);
        System.out.println("填充后: " + Arrays.toString(arr2));
        
        // 4. 复制数组
        int[] arr3 = Arrays.copyOf(arr, 3);  // 复制前3个
        System.out.println("复制前3个: " + Arrays.toString(arr3));
        
        int[] arr4 = Arrays.copyOfRange(arr, 2, 5);  // 复制[2,5)
        System.out.println("复制[2,5): " + Arrays.toString(arr4));
        
        // 5. 比较数组
        int[] a1 = {1, 2, 3};
        int[] a2 = {1, 2, 3};
        System.out.println("数组相等: " + Arrays.equals(a1, a2));
    }
}

9、去重

复制代码
public class ArrayRemoveDuplicates {
    public static void main(String[] args) {
        int[] arr = {1, 2, 2, 3, 4, 4, 5, 5, 5};
        
        // 假设数组已排序
        Arrays.sort(arr);
        
        int j = 0;  // 指向不重复元素的最后一个位置
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] != arr[j]) {
                j++;
                arr[j] = arr[i];
            }
        }
        
        // 截取不重复部分
        int[] result = Arrays.copyOf(arr, j + 1);
        System.out.println("去重后: " + Arrays.toString(result));
    }
}

10、寻找数组中缺失的数字

复制代码
public class MissingNumber {
    public static void main(String[] args) {
        int[] arr = {3, 0, 1};  // 缺失2
        
        int n = arr.length;
        int expectedSum = n * (n + 1) / 2;
        int actualSum = 0;
        
        for (int num : arr) {
            actualSum += num;
        }
        
        int missing = expectedSum - actualSum;
        System.out.println("缺失的数字: " + missing);
    }
}

11、合并两个有序数组

复制代码
public class MergeSortedArrays {
    public static void main(String[] args) {
        int[] arr1 = {1, 3, 5, 7};
        int[] arr2 = {2, 4, 6, 8, 10};
        
        int[] result = new int[arr1.length + arr2.length];
        
        int i = 0, j = 0, k = 0;
        
        // 合并
        while (i < arr1.length && j < arr2.length) {
            if (arr1[i] < arr2[j]) {
                result[k++] = arr1[i++];
            } else {
                result[k++] = arr2[j++];
            }
        }
        
        // 处理剩余元素
        while (i < arr1.length) {
            result[k++] = arr1[i++];
        }
        
        while (j < arr2.length) {
            result[k++] = arr2[j++];
        }
        
        System.out.println("合并后: " + Arrays.toString(result));
    }
}

12、数组的优缺点

优点:

  1. 随机访问快:通过索引直接访问,O(1)时间复杂度

  2. 内存连续:CPU缓存友好

  3. 简单易用:基本数据类型,所有语言都支持

缺点:

  1. 固定大小:创建后不能改变大小

  2. 插入删除慢:需要移动元素,O(n)时间复杂度

  3. 内存浪费:必须预留足够空间

相关推荐
洛豳枭薰2 小时前
List梳理
数据结构·windows·list
星火开发设计2 小时前
C++ multiset 全面解析与实战指南
开发语言·数据结构·c++·学习·set·知识
小猪咪piggy2 小时前
【leetcode100】回溯
数据结构·算法
星火开发设计3 小时前
C++ stack 全面解析与实战指南
java·数据结构·c++·学习·rpc··知识
C雨后彩虹4 小时前
书籍叠放问题
java·数据结构·算法·华为·面试
Jasmine_llq4 小时前
《UVA11181 条件概率 Probability|Given》
数据结构·算法·深度优先搜索(dfs)·剪枝(可行性剪枝)·组合枚举(递归暴力枚举)·条件概率统计与归一化
CCPC不拿奖不改名5 小时前
数据处理与分析:pandas基础+面试习题
开发语言·数据结构·python·面试·职场和发展·pandas
宵时待雨6 小时前
数据结构(初阶)笔记归纳2:顺序表的实现
c语言·数据结构·笔记·算法
漫随流水6 小时前
leetcode算法(101.对称二叉树)
数据结构·算法·leetcode·二叉树