当前位置: 首页 > news >正文

数组入门:从零基础到排序算法 - 教程

  1. 数组的概念
    1.1 什么是数组
    数组是由​​相同类型元素​​构成的集合,这些元素在​​内存中连续存储​​。定义一个数组相当于一次性定义了多个变量,这些变量具有相同的数据类型,并通过下标进行访问。

    数组的基本特性:

    • 数组中存放的是一个或多个数据,但元素个数不能为0

    • 数组中存放的多个数据,类型是相同的

    • 数组在内存中是连续存放的

    • 数组的大小在创建时确定,大小不可改变

    1.2 什么是数组元素
    构成数组的每一个数据称为​​数组元素​​。数组元素可以是基本数据类型(如int、double、char)也可以是引用类型(如对象)。

    1.3 什么是数组下标
    数组的下标是元素在数组中的​​位置索引​​,从0开始,依次累加1。下标的界限是:0 ~ 数组长度-1。

    如果访问数组时下标 <0 或 >数组长度-1,会抛出ArrayIndexOutOfBoundsException异常。

    1.4 什么是数组长度
    数组长度表示数组的大小,即数组元素的个数。获取数组长度的方法是:数组名.length。

    注意:数组的大小在分配内存时就已经确定,大小不可改变。

  2. 数组的声明和创建(以一维数组为例)
    2.1 定义数组
    // 数组名在前
    int arr1[];
    // 数组名在后
    int[] arr2;
    2.2 为数组元素分配内存空间

    // 一种方法
    int arr1[] = new int[5];
    // 另一种方法
    double[] arr2;
    arr2 = new double[4];
    new运算符用于为数组元素分配内存,数据类型必须相同。

    2.3 数组元素初始化

    // 第一种写法:动态初始化
    int arr1[] = new int[]{
    1, 2, 3, 4, 5
    };
    // int[]中括号内不可以写数组的大小
    // 第二种写法:静态初始化简化形式
    int arr2[] = {
    1, 2, 3
    };
    // 第三种写法:分步初始化
    double[] arr3;
    arr3 = new double[]{
    1.0, 2.1, 3.2, 4.4
    };
    // 第四种写法:逐个元素初始化
    char []ch4 = new char[4];
    ch4[0] = 'v';
    ch4[1] = 'h';
    ch4[2] = 'n';
    ch4[3] = 'm';
    // 这种写法数组的下标一定不能发生越界

    数组初始化时,如果没有给定初始值,数组元素会有其默认值:

    • 整型默认值为0

    • 浮点型默认值为0.0

    • 布尔型默认值为false

    • 引用类型默认值为null

    2.4 数组元素在内存中的表现形式
    当执行int[] score = new int[5]时:

    • score中存放的是一个引用类型的值(如0xAA01)

    • 这个值是一个指针,指向内存中首地址为0xAA01、长度为5的连续内存空间

    • 由于没有对数组元素初始化,所有元素使用默认值0

  3. 数组的使用
    3.1 找数组元素的最大(小)值,求总和,求平均

    public static void main(String[] args){
    int[] arr = new int[]{
    23, 34, 54, 13, 45
    };
    int max = arr[0];
    int min = arr[0];
    int sum = 0;
    for(int i = 1; i < arr.length; i++){
    if(max < arr[i]){
    max = arr[i];
    }
    if(min > arr[i]){
    min = arr[i];
    }
    sum += arr[i];
    }
    System.out.println("最大值为:" + max);
    System.out.println("最小值为:" + min);
    System.out.println("总和为:" + sum);
    System.out.println("平均值为:" + (double)sum/arr.length);
    }

    3.2 对数组排序
    3.2.1 冒泡排序

    public static void main(String[] args) {
    int score[] = new int[80000];
    Random random = new Random();
    for (int i = 0; i < score.length; i++) {
    score[i] = random.nextInt(80000);
    }
    long start = System.currentTimeMillis();
    // 冒泡排序
    for (int i = 0; i < score.length-1; i++) {
    for (int j = 0; j < score.length-i-1; j++) {
    if(score[j] > score[j+1]){
    int tmp = score[j];
    score[j] = score[j+1];
    score[j+1] = tmp;
    }
    }
    }
    long end = System.currentTimeMillis();
    System.out.println("耗时:" + (end-start) + "毫秒");
    }

    结果:80000个数使用冒泡排序大约用时8450毫秒

    3.2.2 选择排序

    public static void main(String[] args) {
    int[] arr = new int[80000];
    Random r = new Random();
    for (int i = 0; i < arr.length; i++) {
    arr[i] = r.nextInt(80000);
    }
    long start = System.currentTimeMillis();
    // 选择排序
    for (int i = 0; i < arr.length-1; i++) {
    int minIndex = i;
    int min = arr[i];
    for(int j = i+1; j < arr.length; j++){
    if (arr[j] < min){
    min = arr[j];
    minIndex = j;
    }
    }
    int tmp = arr[i];
    arr[i] = arr[minIndex];
    arr[minIndex] = tmp;
    }
    long end = System.currentTimeMillis();
    System.out.println("耗时:" + (end-start) + "毫秒");
    }

    结果:80000个数使用选择排序大约用时1800毫秒

    3.2.3 插入排序

    public static void main(String[] args) {
    int[] arr = new int[80000];
    for (int i = 0; i <
    80000; i++) {
    arr[i] = (int)(Math.random() * 80000);
    }
    long start = System.currentTimeMillis();
    // 插入排序
    for (int i = 1; i < arr.length; i++) {
    int j = i;
    while (j >
    0){
    if (arr[j] < arr[j-1]){
    int temp = arr[j];
    arr[j] = arr[j-1];
    arr[j-1] = temp;
    j--;
    } else {
    break;
    }
    }
    }
    long end = System.currentTimeMillis();
    System.out.println("耗时:" + (end-start) + "毫秒");
    }

    结果:80000个数使用插入排序大约用时700毫秒

    3.2.4 快速排序

    public static void main(String[] args){
    int[] arr = new int[80000];
    for (int i = 0; i <
    80000; i++) {
    arr[i] = (int)(Math.random() * 800000);
    }
    long s = System.currentTimeMillis();
    quickSort(arr, 0, arr.length-1);
    long e = System.currentTimeMillis();
    System.out.println("耗时:" + (e-s) + "毫秒");
    }
    public static void quickSort(int[] arr, int first, int last){
    if (first >= last) {
    return;
    }
    int low = first;
    int high = last;
    int mid_value = arr[first];
    while (low < high){
    while (low < high && arr[high] >= mid_value){
    high -= 1;
    }
    arr[low] = arr[high];
    while (low < high && arr[low] < mid_value){
    low += 1;
    }
    arr[high] = arr[low];
    }
    arr[high] = mid_value;
    quickSort(arr, first, low-1);
    quickSort(arr, low+1, last);
    }

    结果:80000个数使用快速排序大约用时20毫秒

  4. Arrays类
    4.1 什么是Arrays类
    Arrays类是Java提供的数组工具类(java.util.Arrays),包含各种操作数组的静态方法。由于数组本身没有提供很多操作方法,Arrays类填补了这一空白。
    4.2 常用方法
    4.2.1 查找数组元素:binarySearch方法

    public static void main(String[] args){
    int[] arr = new int[] {
    10, 50, 40, 30
    };
    Arrays.sort(arr);
    // 排序后:10, 30, 40, 50
    int index = Arrays.binarySearch(arr, 10);
    System.out.println(index);
    // 0
    index = Arrays.binarySearch(arr, 0);
    System.out.println(index);
    // -1
    index = Arrays.binarySearch(arr, 45);
    System.out.println(index);
    // -4
    index = Arrays.binarySearch(arr, 90);
    System.out.println(index);
    // -5
    }

    binarySearch方法使用二分查找算法,前提是数组必须已排序。

    4.2.2 数组转字符串:Arrays.toString(array)

    public static void main(String[] args){
    int[] arr1 = {
    10, 50, 40, 30, 89, 67, 4, 678
    };
    Arrays.sort(arr1);
    System.out.println(Arrays.toString(arr1));
    // 输出:[4, 10, 30, 40, 50, 67, 89, 678]
    }

    4.2.3 填充数组:Arrays.fill(array, val)

    public static void main(String[] args){
    int[] arr1 = {
    10, 50, 40, 30, 89, 67, 4, 678
    };
    Arrays.fill(arr1, 30);
    System.out.println(Arrays.toString(arr1));
    // 输出:[30, 30, 30, 30, 30, 30, 30, 30]
    }

    4.2.4 数组的比较:Arrays.equals(array1, array2)

    public static void main(String[] args) {
    int[] arr1 = {
    10, 50, 40, 30
    };
    int[] arr2 = {
    10, 50, 40, 30
    };
    int[] arr3 = {
    60, 50, 85
    };
    System.out.println(Arrays.equals(arr1, arr2));
    // true
    System.out.println(Arrays.equals(arr1, arr3));
    // false
    }

    4.2.5 数组的排序:Arrays.sort(array)
    // 数组全部排序

    public static void main(String[] args){
    int[] arr1 = {
    10, 50, 40, 30
    };
    Arrays.sort(arr1);
    System.out.println(Arrays.toString(arr1));
    // 输出:[10, 30, 40, 50]
    }
    // 指定范围排序
    public static void main(String[] args){
    int[] arr1 = {
    10, 50, 40, 30, 89, 67, 4, 678
    };
    Arrays.sort(arr1, 3, arr1.length-1);
    System.out.println(Arrays.toString(arr1));
    // 输出:[10, 50, 40, 4, 30, 67, 89, 678]
    }

    4.2.6 数组的复制:Arrays.copyOf(array, length)

    public static void main(String[] args){
    int[] arr1 = new int[] {
    10, 50, 40, 30
    };
    // 将arr1复制成长度为3的新数组arr2
    int[] arr2 = Arrays.copyOf(arr1, 3);
    System.out.println(Arrays.toString(arr2));
    // [10, 50, 40]
    }
  5. 多维数组(以二维数组为例)
    5.1 定义数组
    // 数组名在前

    int arr1[][];

    // 数组名在后

    int[][] arr2;

    5.2 为数组元素分配内存空间
    // 一种方法

    int arr1[][] = new int[5][4];

    // 另一种方法

    double[][] arr2;
    arr2 = new double[5][4];

    多维数组是"数组的数组",二维数组是最常见的多维数组,可以理解为表格或矩阵。

    5.3 数组元素初始化

    // 第一种写法
    int arr1[][] = new int[][] {
    {1, 5},
    {2, 4, 2},
    {3, 7, 9, 5}
    };
    // 第二种写法
    int arr2[][] = {
    {1, 5},
    {2, 4, 2},
    {3, 7, 9, 5}
    };
    // 第三种写法
    double[][] arr3;
    arr3 = new double[][] {
    {1.0, 5.1},
    {2.2, 4.3, 2.4},
    {3.5, 7.6, 9.7, 5.8}
    };
    // 第四种写法:逐个元素初始化
    char[][] ch4 = new char[3][2];
    ch4[0][0] = 'v';
    ch4[0][1] = 'h';
    // ...
    ch4[2][0] = 'h';
    ch4[2][1] = 'm';

    注意:Java中的多维数组实际上是"不规则数组",每个子数组的长度可以不同。

    5.4 多维数组的应用场景
    多维数组常用于以下场景:

    • 图像处理(像素矩阵)
    • 游戏开发(地图、棋盘)
    • 数学计算(矩阵运算)
    • 数据分析(表格数据)
    • 科学计算(三维坐标)

http://www.hskmm.com/?act=detail&tid=14956

相关文章:

  • 用C/C++重构PowerShell:全面绕过安全机制的技术解析
  • Optuna v4.5新特性深度解析:GPSampler实现约束多目标优化
  • 题解:P4769 [NOI2018] 冒泡排序
  • 2025/9/23
  • Tita:更频繁的绩效考核周期的好处
  • 详细介绍:【Linux】Linux文件系统详解:从磁盘到文件的奥秘
  • Which side of a 2d curve is a point on
  • 20250923
  • CCPC秦皇岛 2023 M Inverted
  • 大三上第一篇日志
  • 0923模拟赛总结
  • Hive采用Tez引擎出现OOM的处理办法
  • 0基础读CCFA(TPDS)论文—面向多 GPU 平台机器学习训练的通用性能建模
  • Hetao P10588 十载峥嵘桀骜 题解 [ 紫 ] [ 树的直径 ] [ 矩阵加速 DP ] [ 状态设计优化 ]
  • 用 Julia 提取轮廓和字符特征进行验证码识别
  • VMware之后下一个消失的永久许可,Citrix Netscaler VPX旧版许可已经失效了!你升级了吗?
  • Julia 实现基于模板匹配的验证码识别方法
  • 用 Julia 的频域滤波技术识别含干扰线的验证码
  • 第9节-子查询-ALL - 详解
  • 软件工程感想
  • n8n+MySQL实现数据库查询!
  • My Tricks
  • 完整教程:机器学习入门,支持向量机
  • 谈谈对软件工程的理解
  • firewalld 端口流量转发
  • [PaperReading] Qwen2-VL: Enhancing Vision-Language Model’s Perception of the World at Any Resolution
  • [PaperReading] MemGPT: Towards LLMs as Operating Systems
  • 总线的性能指标
  • VoxCPM:新一代高拟真语音生成模型
  • Day20封装的初步认识