【Java基础】数组的基本操作、复制、扩容、排序以及在内存中的划分

思维导图

数组

一、数组的概念

概念:一组连续的存储空间,存储多个相同类型的值

特点:类型相同、长度固定


二、数组的基本操作

2.1 创建数组

第一种方式

// 1 声明数组
int[] array1;
// 2 初始化数组
array1 = new int[12];

第二种方式

int[] array2 = new int[12];

第三种方式

int[] array4 = new int[]{1, 3, 1, 4};

第四中方式

int[] array3 = {5, 2, 0, 1, 3, 1, 4};

2.2 修改数组元素

array1[0] = 5;
array1[1] = 2;
array1[2] = 0;

2.3 访问数组元素

System.out.println(array1[0]);

2.3 遍历数组

常规遍历

for(int i = 0; i < array1.length; i++) {
    System.out.println(array1[i]);
}

for 增强遍历

for (int value : array1) {
    System.out.println(value);
}

2.4 小练习

给定一个整数数组,统计数组中所有元素的平均值

// 给定一个整数数组,统计数组中所有元素的平均值
public void averageCount() {
    int[] array = {12, 25, 99, 99, 3, 15, 1, 25};
    int sum = 0;
    double average = 0;
    for(int i = 0; i < array.length; i++) {
        sum += array[i];
    }
    average = sum / array.length;
    System.out.printf("%.2f", average);
}

给定一个整数数组,读入一个整数n,如果n在数组中存在,输出下标,不存在则输出-1

// 给定一个整数数组,读入一个整数n,如果n在数组中存在,输出下标,不存在则输出-1
public void judge() {
    int[] array = {5, 2, 0, 1, 3, 1, 4};
    boolean exist = false;
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    for(int i = 0; i < array.length; i++) {
        if (n == array[i]) {
            System.out.println("存在,下标: " + i);
            exist = true;
        }
    }
    if (!exist) {
        System.out.println(-1);
    }
}

控制台输入5个城市名称,用数组保存,并遍历输出

// 控制台输入5个城市名称,用数组保存,并遍历输出
public void saveCity() {
    String[] citys = new String[5];
    Scanner scanner = new Scanner(System.in);
    for(int i = 0; i < citys.length; i++) {
        String input = scanner.next();
        citys[i] = input;
    }
    for (String city : citys) {
        System.out.print(city + " ");
    }
}

三、数组在内存中的划分

数组属于引用类型

  • 栈:栈中存放数组的引用(地址)

  • 堆:堆中存放数组的内容

两个数组,在内存中的划分

在这里插入图片描述

将一个数组直接赋值给另一个数组时的内存图

  • 数组是引用类型,直接赋值时赋值的是数组的引用(地址)
  • 所以将array1的地址给array2时,它们两个在栈中存放的地址就是同一个了,指向堆中同一个位置
  • 所以当修改array1或者array2的时候,它们两个的值会同时变,因为是同一个内容
int[] array1 = {1, 2, 3};
int[] array2 = new int[3];

array2 = array1;

在这里插入图片描述


四、数组的常用操作

4.1 数组的复制

第一种方法:循环

public void arrayCopy1() {
    int[] array1 = {5, 2, 0};
    int[] array2 = new int[array1.length];
    for(int i = 0; i < array1.length; i++) {
        array2[i] = array1[i];
    }
    for (int value : array2) {
        System.out.print(value + " ");
    }
}

第二种方法:clone

public void arrayCopy2() {
    int[] array1 = {5, 2, 0};
    int[] array2;
    array2 = array1.clone();
    for (int value : array2) {
        System.out.print(value + " ");
    }
}

第三种方法:Arrays.copyOf()

public void arrayCopy3() {
    int[] array1 = {5, 2, 0};
    int[] array2;
    // 第一个参数:要复制的数组
    // 第二个参数:新数组的大小(如果新长度 > 原数组长度,则用0填充)
    array2 = Arrays.copyOf(array1, 5);
    for (int value : array2) {
        System.out.print(value + " "); // 结果: 5 2 0 0 0
    }
}

第四种方法:Arrays.copyOfRange()

public void arrayCopy4() {
    int[] oldArray = {5, 2, 0, 1, 3, 1, 4};
    int[] newArray;
    // 复制[0, 5)的数组元素 到新数组中
    // 如果复制长度 < 原数组长度,则就截取部分
    // 如果复制长度 > 原数组长度,则用0填充
    newArray = Arrays.copyOfRange(oldArray, 0, 5);
    for (int value : newArray) {
        System.out.print(value + " ");
    }
}

第五种方法:System.arraycopy()

public void arrayCopy5() {
    int[] oldArray = {5, 2, 0, 1, 3, 1, 4};
    int[] newArray = new int[oldArray.length];
    // 参数: (原数组 原数组起始下标 新数组 新数组起始下标 复制长度)
    // 也就是从原数组的0位置开始复制,复制到新数组从0开始的位置
    System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
    for (int value : newArray) {
        System.out.print(value + " ");
    }
}

4.1 数组的扩容

思路:

  1. 创建一个大于原数组的新数组
  2. 将原数组的元素复制到新数组中

就是将原数组中的元素,放到了一个更大的地方,就实现了扩容

/*
数组扩容
1. 创建一个大于原数组的新数组
2. 将原数组的元素复制到新数组中
 */
public int[] arrayExpand(int[] oldArray, int newLength) {
    int[] newArray = new int[newLength];
    if (newLength < oldArray.length) {
        System.out.println("扩容后的数组长度不能小于原数组长度");
    } else {
        // 将原数组的元素复制到新数组中
        newArray = Arrays.copyOf(oldArray, newLength);
    }
    return newArray;
}

方法测试

int[] oldArray = {5, 2, 0, 1, 3, 1, 4};

int[] newArray = arrayTest.arrayExpand(oldArray, 10);

结果

5 2 0 1 3 1 4 0 0 0 

4.3 数组作为参数

参数传递时(数组是引用类型)

  • 如果传递的是基本数据类型,则传递的是值
  • 如果传递的是引用数据类型,则传递的是引用
    public static void printArray(int[] array) {
        for (int value : array) {
            System.out.print(value + " ");
        }
    }

因为数组是引用类型,传递的是引用

  • 当在其它地方修改数组时,两者的数据都会变
  • 因为实际上修改的那个数组和此数组指向的内存空间是一个地方,所以修改一个,另一个也会变

可变参数

  • 只能有一个
  • 必须在最后
public static void printArray(int... array) {
    for (int value : array) {
        System.out.print(value + " ");
    }
}

// 调用
printArray(12, 25, 99, 99);
printArray(newArray);

五、数组的排序

更详细的讲解冒泡排序选择排序插入排序希尔排序快速排序

5.1 冒泡排序

// 冒泡排序
public int[] bubbleSort(int[] array) {
    for(int i = 0; i < array.length; i++) {
        for(int j = 0; j < array.length - i - 1; j++) {
            if (array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
    return array;
}

5.2 选择排序

// 选择排序
public int[] selectSort(int[] array) {
    for(int i = 0; i < array.length; i++) {
        int minIndex = i;
        for(int j = i + 1; j < array.length; j++) {
            if (array[minIndex] > array[j]) {
                minIndex = j;
            }
        }
        if (minIndex != i) {
            int temp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = temp;
        }
    }
    return array;
}

5.3 插入排序

第一种方式

// 插入排序
public int[] insertSort(int[] array) {
    for(int i = 0; i < array.length; i++) {
        for(int j = i; j > 0; j--) {
            if (array[j] < array[j - 1]) {
                int temp = array[j];
                array[j] = array[j - 1];
                array[j - 1] = temp;
            }
        }
    }
    return array;
}

第二种方式

// 插入排序
public int[] insertSort2(int[] array) {
    for(int i = 0; i < array.length; i++) {
        int temp = array[i];
        int j = i;
        while (j > 0 && temp < array[j - 1]) {
            array[j] = array[j - 1];
            j--;
        }
        if (i !=j) {
            array[j] = temp;
        }
    }
    return array;
}

5.4 希尔排序

// 希尔排序
public int[] shellSort(int[] array) {
    int gap = array.length;
    while (true) {
        gap /= 2;
        for(int i = 0; i < gap; i++) {
            // 插入排序
            for(int j = i + gap; j < array.length; j += gap) {
                int temp = array[j]; // temp是取出的要比较的值
                int pos = j; // pos是向前移的指针
                // 向前找,如果找到更大的元素,则向后移
                while (pos > 0 && array[pos - gap] > temp) {
                    array[pos] = array[pos - gap];
                    pos -= gap; // pos指针向前移 步长gap
                }
                // 结束后,将temp交换到这里
                array[pos] = temp;
            }
        }
        if (gap == 1) {
            break;
        }
    }
    return array;
}

5.5 快速排序

// 快速排序
public void quickSort(int[] array, int low, int high) {
    if (low >= high) {
        return;
    }
    int pivot = array[low];
    int left = low;
    int right = high;
    while (low < high) {
        // 在右面找到第一个小于基准的数
        // 也就是大于基准时,high指针就左移
        while (low < high && pivot <= array[high]) {
            high--;
        }
        int temp = array[high];
        array[high] = array[low];
        array[low] = temp;

        // 在左面找到第一个大于基准的数
        // 也就是小于基准时,low指针就右移
        while (low < high && pivot >= array[low]) {
            low++;
        }
        temp = array[high];
        array[high] = array[low];
        array[low] = temp;

    }
    quickSort(array, left, low - 1);
    quickSort(array, low + 1, right);
}

六、多维数组

6.1 二维数组

// 二维数组
public void ArrayTwoTest() {
    // 创建二维数组
    int[][] array = new int[5][5];
    
    // 先声明,再分配空间
    int[][] array1;
    array1 = new int[3][3];

    // 创建二维数组并赋值
    int[][] array2 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    // 访问二维数组
    System.out.println(array[0][1]);

    // 二维数组赋值
    array[2][2] = 12;
    array[1][3] = 25;

    // 二维数组的遍历
    for(int i = 0; i < array.length; i++) {
        for(int j = 0; j < array[i].length; j++) {
            System.out.print(array[i][j] + " ");
        }
        System.out.println();
    }
}

6.2 小练习

// 杨辉三角形
public void yanghui() {
    int[][] array = new int[12][];

    for(int i = 0; i < array.length; i++) {
        array[i] = new int[i + 1];
        // 填充空格
        for(int k = 0; k < array.length - i - 1; k++) {
            System.out.print(" ");
        }
        for(int j = 0; j < array[i].length; j++) {
            if (j == 0 || i == j) {
                array[i][j] = 1;
            } else {
                array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
            }
            System.out.print(array[i][j] + " ");
        }
        System.out.println();
    }
}

七、查找算法

7.1 二分法查找

// 二分查找
public int binarySearch(int[] array, int target) {
    int low = 0;
    int high = array.length - 1;
    int mid = (low + high) / 2;
    while (low < high) {
        if (array[mid] == target) {
            return mid;
        } else if (target > array[mid]) {
            low = mid + 1;
        } else if (target < array[mid]) {
            high = mid - 1;
        }
        if (low == high) {
            return -1;
        }
        mid = (low +high) / 2;
    }
    return -1;
}

注意:二分法查找只能对有序序列进行查找

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值