最简单最基本的数据结构——数组(基于Java)

数组(Array

数据结构

存储数据的结构方式。存储数据的结构方式不一样,直接涉及到数据的增删改查的效率不一样

常见的数据结构

包含:数组、队列、链表、树、哈希表、栈…

数组:查询快,增删慢

队列、链表、栈:增删快,数据量小的时候

哈希表:增删改查很快,无序的

树:增删改查很快,有序的

数组的定义

数组是一个存储相同数据类型的有序集合| 容器,数组属于引用数据类型

数组的索引|下标从0开始递增

public class ForAndArrayTest{
    public static void main(String[] args){
        int arr[] = new int[]{1,2,3,4,5};
        for(int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }
    }
}

特点:相同数据类型、有序的

画图分析:
在这里插入图片描述

虚拟机上的内存分为栈内存,堆内存

栈内存

存储:局部变量

若是基本数据类型的局部变量,栈内存中存储的是数据值

若是引用数据类型的局部变量,栈内存中存储的是对象在堆中的地址

特点:

  1. 栈内存遵守“先进后出,后进先出”的特点

  2. 栈内存是一块连续的存储空间,由虚拟机分配,效率高

    画图分析:
    在这里插入图片描述

  3. 每个线程都拥有一个独立的栈内存,避免了数据干扰,用于存放该线程执行方法的信息

    单线程同步:同一时间只能做一件事情

堆内存

存储:所有引用数据类型,包括new出来的对象和数组

特点:

  1. 堆内存不是块连续的存储空间,分配灵活,效率低

    画图分析:
    在这里插入图片描述

  2. 多个线程共享一个堆内存,被所有的线程共享

    多线程异步:同一时间可以做多件事情

补充:在方法体或代码块中定义的变量,称为局部变量

目前见过的异常有哪些?

  1. 空指针异常(java.lang.NullPointerException)

    引起:对空对象执行某些操作时,就会引发NullPointerException空指针异常

    比如:操作数组中元素时,首先应该检查该数组是否引用了堆中对象的地址

    代码展示:

    public class MakeException2{
        public static void main(String[] agrs){
            int arr1[] = {1,2,3,4};
            int arr2[] = arr1;
            arr1 = null;
            System.out.println(arr1[0]); // NullPointerException
            System.out.println(arr2[2]); // 3
        }
    }
    

    画图分析:
    在这里插入图片描述

    运行错误截图:
    在这里插入图片描述

  2. 数组索引越界异常(java.lang.ArrayIndexOutofBoundsException)

    引起:操作数组的索引值越界,索引值合法取值范围是[0,数据长度-1]

    代码展示:

    public class ArrayIndexOutofBoundsExceptionTest{
        public static void main(String[] args){
    		int arr[] = {1,2,3,4,5};
            System.out.println(arr[5]);
        }   
    }
    

    运行错误截图:
    在这里插入图片描述

  3. 算术异常(java.lang.ArithmeticException

    引起:分母为0

    代码展示

    public class MakeException1{
        public static void main(String[] args){
            int a = 1 / 0;
            System.out.println(a);
        }
    }
    

    运行错误截图:
    在这里插入图片描述

  4. 输入类型不匹配异常(inputMismatchException)

    代码展示

    import java.util.Scanner;
    public class ScannerTest03{
        public static void main(String[] args){
            System.out.println("请输入整数:");
            int num = new Scanner(System.in).nextInt();
            System.out.println("这个数为num = " + num);
        }
    }
    

    运行错误截图:
    在这里插入图片描述

数组的核心特点
  1. 数组是一块连续的存储空间
  2. 数组一旦创建成功,那么空间长度就不能改变了
数组的优势

查询效率是所有数据结构中最高的

数组的劣势

数组执行插入、删除操作时,效率低

代码展示:

public class ArrayDemo03{
    public static void main(String[] args){
        int arr1[] = {1,2,3,4,5};
        int[] arr2 = arr1;
        arr2[2] = 33;
        System.out.println(arr1[2]); // 输出33
    }
}

画图分析:
在这里插入图片描述

运行截图:
在这里插入图片描述

代码展示:

public class ArrayDemo04{
    public static void main(String[] args){
        int[] arr = {11,22,33,44,55};
        arr[1] = 222;
        arr[4] = 555;
        System.out.println(arr[0]); // 11
        System.out.println(arr[1]); // 222
    }
}

运行截图:
在这里插入图片描述

画图说明:
在这里插入图片描述

核心总结:删除插入慢,查询修改快

掌握以下两点:

  1. 为什么索引从0开始递增?

  2. 为什么数组的查询效率最高?

    答:因为课通过公司快速寻址,课快速找到元素所对应的功能

删除数组元素的操作

错误分析:
在这里插入图片描述

若像以上如此删除数组中的元素,那“数组是块连续的存储空间”就不成立了

正确的实现步骤:

  1. 把删除元素及其之后的所有元素往前挪动一位
  2. 最为一位元素的默认值为默认值,比如int类型默认值为0

需求:

  1. 删除数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}索引为2的元素,删除后:{5, 12, 18, 77, 76, 45, 28, 59, 72,0}。

代码展示:

public class DelArray{
    public static void main(String[] args){
        int arr = {11,15,16,45,78,45,90,12,17};
        int index = 2;
        for(int i = index;i < arr.length - 1;i++){
            arr[i] = arr[ i + 1];
        }
        arr[arr.length - 1] = 0;
        for(int temp : arr){
            System.out.print(temp + " ")
        }
    }
}

画图分析:
在这里插入图片描述

运行截图:
在这里插入图片描述

插入数组元素的操作

错误分析:
在这里插入图片描述

以上这样直接插入数组元素是不正确的,这样做“”数组以一块连续的存储空间“就不成立了

正确的实现步骤:

  1. 检查元素是否需要扩容,当数组空间长度和实际存放元素的个数相等时,就要扩容
    1. 新建一个比原数组空间长度更大的新数组,新数组空间长度由需求而定
    2. 把元素中的元素拷贝一份到新数组中
    3. 让原数组保存新数组的地址
  2. 把插入索引及其之后所有元素从后往前挪动一位
  3. 把需插入的元素赋值到新插入索引的位置

代码展示:

public class InsertElement{
    public static void main(String[] args){
        int arr[] = {11,15,16,45,78,45,90,12,17};
        int index = 2;
        int size = 9;
        int value = 222;
        if(arr.length == size){
            int newArr[] = new int[arr.length + 1];
 			for(int  i = 0;i <  arr.length;i++){
                newArr[i] = arr[i];
            }
            for(int temp : arr){
                System.out.println(temp);
            }
            arr = newArr;
        }
        
        for(int i = arr.length - 2;i >= index;i--){
             arr[i+1] = arr[i];
        }
        arr[index]  = value;
        
       System.out.print("插入新元素后,遍历数组中的元素:");
        for(int  temp:arr){
            System.out.print(temp + " ");
        }                                  
    }
}

画图分析:
在这里插入图片描述

运行截图:
在这里插入图片描述

需求:

  1. 将数组反序输出,原数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72},反序输出后{72,59,28,45,76,77,18, 90,12,5}。

画图分析:
在这里插入图片描述

代码展示:

// 方式一:
public class ReverseArrayElement{
    public static void mian(String[] args){
        int arr[] = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
        for(int i = 0; i< arr.length / 2 ;i++){
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i]  = temp;
        }
        for(int temp: arr){
            System.out.print(temp + " ");
        }
    }
}

运行截图:
在这里插入图片描述

画图分析:
在这里插入图片描述

代码展示:

public class ReverseArrayTest{
    public static void main(String[] args){
        int arr[] = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
         int newArr[] = new int[arr.length];
        for(int i = 0;i < arr.length;i++){
            newArr[arr.length - i - 1] = arr[i];
        }
        for(int temp : newArr){
            System.out.print( temp + " ");
        }
    }
}

运行截图:
在这里插入图片描述

补充知识:直接输出数组,得到的是数组第一个元素的首地址

代码展示:

public class AddressTest{
    public static void main(String[] args){
        int arr[] = {1,11,12,13,15};
        System.out.println(arr); // 输出的是数组第一个元素的首地址
    }
}

画图分析:
在这里插入图片描述

运行截图:
在这里插入图片描述

代码展示:

public class AddressTest1{
    public static void main(String[] arhs){
        char arr[] = {'a','b','c','d'};
        System.out.println(arr);
    }
}

运行截图:
在这里插入图片描述


冒泡排序法

算法核心:相邻两个元素做比较,若前一个元素> 后一个元素,则两元素交换位置

排序过程总结:每一趟相邻两个元素比较完毕,都能确定一个最大值

需求:使用冒泡排序实现对 int[] arr ={3,5,1,7,6,2,4} 数组进行升序排序

画图分析:
在这里插入图片描述

代码展示:

public class ArraySortTest{
    public static void main(String[] args){
        int arr[] ={3,5,1,7,6,2,4};
        for(int i = 0;i< arr.length - 1;i++){
            for(int j = 0;j< arr.length - 1 - i;j++){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                     arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        for(int temp : arr){
            System.out.print(temp + " ");
        }
    }
}

运行截图:
在这里插入图片描述

练习:

  1. 获取数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}的最大值,也就是该数组的元素90。

    代码展示:

    public class MaxValue{
        public static void main(String[] args){
            int arr[] = {5,12,90,18,77,76,45,28,59,72};
            int max = arr[0];
            for(int i = 1;i<arr.length; i++){
                if(max < arr[i]){
                    max  = arr[i];
                }
            }
            System.out.print("最大值为"+max);
        }
    }
    

    运行截图:
    在这里插入图片描述

  2. 获取数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}的最大值索引

    代码展示:

    public class MaxIndex{
        public static void main(String[] args){
            int arr[] = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
            int maxIndex = 0;
            if(int i = 1;i < arr.length;i++){
                if(arr[maxIndex] < arr[i]){
                    maxIndex = i;
                }
            }
            System.out.println("最大值索引为" + maxIndex);
        }
    }
    

    运行截图:
    在这里插入图片描述

  3. 获取数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}的最小值

    代码展示:

    public class MinValue{
        public static void main(String[] arhs){
            int arr[] = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
            int min = arr[0];
            for(int i = 1;i<arr.length;i++){
                if(min>arr[i]){
                    min = arr[i];
                }
            }
            System.out.println("最小值为 min = " + min);
        }
    }
    

    运行截图:
    在这里插入图片描述

  4. 获取数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}的最小值索引

    代码展示:

    public class MinIndex{
        public static void main(String[] args){
            int arr[] = {5,12,90,18,77,76,45,28,59,72};
            int minIndex = 0;
            for(int i = 1 ;i <arr.length;i++){
                if(arr[minIndex] > arr[i]){
                    minIndex = i
                }
            }
            System.out.println("最小值索引minIndex = "  + minIndex);
        }
    }
    

    运行截图:
    在这里插入图片描述

  5. 获取元素59在数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}中的第一次出现的索引。

    代码展示:

    public class FindIndex{
        public static void main(String[] args){
            int arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
            int value = 59;
            int index = -1;
            for(int i = 0;i < arr.length;i++){
                if(arr[i] == value){
                   index  = i;  
                   break;
                }
            }
            System.out.println("索引为 index = "  + index);
        }
    }
    

    运行截图:
    在这里插入图片描述


此文章于11月27日编辑完毕,小编也是个初学者,或许有些内容写的有错误的,我对自己的要求是:有错改之,无错加勉。还望大家能在评论区指点迷津,不胜感激,同时也希望大家口下留情!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔走中的蜗牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值