数组的学习

本文详细介绍了Java数组的基本概念,包括定义、初始化(静态和动态)、元素访问方法,并讨论了内存分配和可能出现的异常,如数组越界和空指针异常。此外,还提供了数组操作实践,如遍历、查找、插入、删除和修改,以及排序算法实例,如冒泡、选择和插入排序。
摘要由CSDN通过智能技术生成

一.数组的概念

         数组是用于存储一组同类型数据的数据结构,在内存中占用一段连续的空间。

二.数组定义和初始化

1.定义

数据类型  [] 变量名 ;

eg. int [] arr;

含义:定义了一个int类型的数组,变量名为arr

数据类型 变量名[];

eg. int arr[];

含义:定义了一个int类型的变量,变量为arr数组

2.初始化

静态初始化

数据类型 [] 变量名 = new 数据类型[]{数据1,数据2....};

eg. int [] arr = new int [] {1,2,3,4};

简化格式

数据类型 [] 变量名 = {数据1,数据2...};

eg. int [] arr = {1,2,3,4} ;

动态初始化

只声明数组的长度,不赋值。

格式:数据类型 [] 变量名 = new 数据类型[数组长度];

eg. int [] arr = new int [3];

注意:动态初始化时,只声明了数组的长度,但系统会给数组分配默认值,整数型为0,浮点数为0.0,字符型默认为空字符,布尔类型为false,引用类型为null   

三、数组元素访问

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

运行结果如下:

由上图得,通过数组名[索引] 可以访问数组中得元素;   其中索引指的是数组中数据的编号方式,从0开始。

四、内存分配

先简要得介绍一下java中的栈和堆,java的运行时内存可分为堆内存,栈内存,方法区和本地方法栈,栈中保存的是局部变量;堆中保存的是一些动态产生的数据,比如new出来的对象

先看一段代码

public static void main(String [] args){
// 1
    int [] arr = {2,1,4};
// 2
    arr [0] = 1; 
// 3
    int []arr1 = arr;
// 4
    arr = null;
// 5
    arr1[2] = 7;

}

执行1 时

 执行2时

执行3时

 

执行4时

执行 5时

五、可能出现的异常

1.数组越界(ArrayIndexOutOfBoundsException)

访问了不在数组索引范围内(o~length-1)的元素

2.空指针异常

访问的数组不再指向堆内存中的数据

六、数组练习

1.遍历

for循环遍历

public class ArrayTest {
    public static void main(String[] args) {
        int [] arr = {1,2,3,4};
        PrintArr(arr);
    }

public static void PrintArr(int [] arr){
        for(int i = 0; i < arr.length; i++){
            System.out.println(arr[i];)
}
    }
}

for each遍历

public class ArrayTest {
    public static void main(String[] args) {
        int [] arr = {1,2,3,4};
        PrintArr(arr);

    }
    public static void PrintArr(int [] arr){
        for (int i : arr) {
            System.out.println(i);
        }
    }
}

2.找最值

    public static int GetMax(int [] arr) throws NullPointException{
        if (arr!=null ){
            int max = arr[0];
            for (int i = 0; i < arr.length; i++) {
                if (max < arr[i]){
                    max = arr[i];
                }
            }
            return max;
        }
        else
            throw new NullPonintException;

3.插入元素

前提条件:数组有足够的空间容纳插入元素

    public static void insert(int[] arr, int num, int index, int count) {
/*
 num:插入的值
 index:插入下标
 count:当前数组数据个数
 */
        int temp;
// 预计插入位置不在数组索引范围内
        if (index >= arr.length){
            System.out.println("***");
            return;
        }
//  在没有元素的位置插入
           if(index > count)
             arr[index] = num;
           else{
//  在有元素的序列中插入,从插入位置开始,整体后移
            for (int i = count; i > index; i--) {
                arr[i] = arr[i - 1];
            }
            arr[index] = num;
            }
        
    }

4.删除

public static void del(int []arr, int num){
   for (int i = 0; i <arr.length; i++) {
            if (arr[i] == num){
            for (int j=i;j<arr.length-1;j++){
                arr[j] = arr[j+1];
            }
        }
    }
}

5.修改

已知下标的情况,直接赋值即可。

如果是有序序列,可通过二分查找找出元素的下标,再进行修改


    public static void modfiy(int[] arr,int srcNum, int decNum){
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == srcNum){
                arr[i] = srcNum;
            }
        }
    }

6.二分查找

前提:数组是有序的,要查找的元素只有一个

执行的操作:(1)在有序序列中,开始位置定义为左节点,结束位置右节点,并计算出中间节点(2)判断中间节点对应值和待查找key值得关系,相等就返回中间节点并结束查找,大于将右节点更新为中间节点-1,小于将左节点更新为中间节点+1。(3)重复上面两步,直到左节点大于右节点。

图解:

key(查找元素):7

arr(查找数组) = {1,3,5,7,9,11,14,22,29};

  

代码实现

   public static int binarySearch(int []arr, int key){
/*
* @param arr 待查找数组
* @param key 查找数据
* @param return index/-1 返回-1表示未找到
* */
        int index = -1;
        int left = 0;
        int right = arr.length-1;
        int mid;
//  观察第四次,不难看出 [left,right]区间依然是有效的,故left<=right
        while (left<=right){
            mid = left+((right-left)>>1);
//求中间值使用 mid = left+((right-left)>>1);而不用·(mid = left+right)的原因:
//1.内存溢出问题
// eg. 2的31
//2. 负数

            if (key == arr[mid])
                return mid;
            else if (key> arr[mid])
                left = mid+1;
            else
                right = mid-1;
        }
        return -1;
    }
}

7.排序

冒泡排序

   public static void bubble(int []arr){
    /*
     * @param:arr 待排序数组
     * @ return 
     * 
    */
        int temp;
        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]){
                 temp = arr[j];
                 arr[j] = arr[j+1];
                 arr[j+1] = temp;
                }
            }
        }

选择排序

    public static void selectSort(int []arr){
        int minIndex = 0;
        int temp;
//       找出最小值放到一旁,在剩余数据中重复这一操作
        for (int i = 0; i < arr.length-1; i++) {
            minIndex = i;
            for (int j = i ; j < arr.length; j++ ){
//                找出本轮最小值下标
                minIndex = arr[minIndex] < arr[j]?minIndex : j;
        }
//          将当前arr[i]与本轮最小值交换
            temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }

插入排序

  public static void insertSort(int []arr){
        /*
         * @param:arr
         * @ return:
        */
         // 假定我们手中的牌是3 2 9 7 5
        // 从3开始假定其有序,2的时候,发现2<3,就和3交换 2 3 9 7 5
        // 9的时候,我们发现它大于前面的牌,不动
        //...
        // 2 3 7 9 5 ,5比前一个数9小,交换得 2 3 7 5 9,5依然小于 7 ,再次交换,发现5>3,停止交换
        int temp;
        for (int i = 0; i <arr.length-1 ; i++) {
            for (int j = i+1; j > 0 && arr[j] < arr[j-1]; j--) {
//           和前一个元素进行交换
              ArrayUtils.swap(arr,j,j-1);
            }

        }
    }

快速插入排序

    public static void quickSort(int []arr, int left, int right){
        /*
        快排规则
        找出一个数作为数轴,双指针向数轴靠拢,大于放右边,小于放左边
        排一次,然后对左边右边分别递归执行上述步骤,直到子序列中的元素较少,使用插入排序
        如果一直使用快速排序,结束条件为枢轴左侧或右侧只有一个数据
         * @param:
         * @ return:
        */
        // 数组为空或只有一个元素,不做处理
        if (arr ==  null || arr.length == 1 ){
            return;
        }
        // 数组元素小于10,使用插入排序
        if (right - left < 10)
         InsertSort.insertSort(arr, left, right);
        // 进行快排
        // 找出中轴位置,并进行排序
        else{
        int centerAxis = firstSort(arr, left, right);
//        int centerAxis = firstSort1(arr, left, right);
        // 结束第一次排序,分别对两个子序列进行排序
        quickSort(arr, left,centerAxis-1);
        quickSort(arr, centerAxis+1,right);}

    }
    public static int firstSort(int [] arr, int left, int right){
        // 左右指针法实现第一次排序
//        实现思路,left 往右找,直到找到一个大于key的值,停下
//        right往左找,找到一个小于key的值,停下
//        right 和 left交换
//        直到 right<= left
//        结束第一次排序

        int key = arr[right--];
        while(left < right){
           while(arr[left]<=key && right> left)
               left++;
           while (arr[right]>=key && right > left )
               right--;
//           分别找到了左边大于key,右边小于key的值,交换
            ArrayUtils.swap(arr,left,right);
        }
        ArrayUtils.swap(key, left);
        return left;
    }
//    挖坑进行第一次排序找出中轴
    public static int firstSort1(int []arr, int left, int right ){
        int key = arr[right];
//        实现思路,取出最右边值为中枢,从左开始找,找到>key的值放到,right所在处,接着停下
//        right开始找,找到<key的,放到left处
        while (left < right){
            while(arr[left] <= key && left < right )
                left ++;
            arr[right] = arr[left];
            while (arr[right] >= key && left < right)
                right --;
            arr[left] = arr[right];
        }
        arr[right] = key;
        return right;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值