3.1、数组的概述

数组(Array),是多个相同类型数据按一定顺序排列 的集合,并使用一个名字命名,并通过编号的方式 对这些数据进行统一管理。
数组的常见概念
数组名
下标(或索引)
元素
数组的长度
数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
数组的长度一旦确定,就不能修改。
我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
数组的分类:
按照维度:一维数组、二维数组、三维数组、…
按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)

3.2 、一维数组的使用

1. 一维数组的使用:声明
一维数组的声明方式:type var[] 或 type[] var;
Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法
2.一维数组的使用:初始化
动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行
int [] arr = new int [10];
arr[0] = 值;
静态初始化:在定义数组的同时就为数组元素分配空间并赋值。
int [] arr = new int [] {元素,元素和元素之间使用逗号分隔};
int [] arr = new int[] {元素};
3.一维数组的使用:数组元素的引用
定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
数组元素的引用方式:数组名[数组元素下标]
数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6i];
数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]
每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长L度(元素个数)
数组一旦初始化,其长度是不可变的
4.一维数组的使用:数组元素的默认初始化值
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式
对于基本数据类型而言,默认初始化值各有不同
对于引用数据类型而言,默认初始化值为null(注意与0不同!)
方法与数组
5.一维数组的使用:创建数组
Java中使用关键字new来创建数组
如下是创建基本数据类型元素的一维数组
public class Test{
public static void main(String args[]){
int[] s; s = new int[10];
for ( int i=0; i<10; i++ ) {
s[i] =2
i+1;
System.out.println(s[i]);
}
}
}
int[] ages = new int[4];
ages[0] = 12;
ages[1] = 23;
ages[2] = 33;
6.数组的遍历
普通for 使用数组的属性 arr.length 来获取数组的长度
for(int i = 开始索引;索引的范围;每次的步长){
可以对数组中的每一个元素进行精确操作;
}
增强for/for…each
for(遍历对象的类型 每次遍历得到的对象的一个临时保存变量:要遍历的对象(数组名称)){
对数组所有元素的一个运算;
}
普通for和增强for格式区别
运算中普通for可以精确控制操作对象。
增强for必须是整个数组的所有元素无法精 确控制每一个元素
7.数组的内存
在Java中,凡是new出来的对象都存放在堆区。

3.3 方法

完成特定功能的代码块;代码块就是使用{}括起来一-段代码;
方法的声明:访问修饰符[static] 方法的返回值类型
方法名称([形参列表:参数类型( 基本类型/引用类型)
参数名称多个参数之间使用逗号分隔]) {
方法所要具体实现的功能:
}
方法的注意事项:
1 main方法是整个程序的入口方法对于一个javase程序始终是从main方法开始执行。
2 main方法的声明形式是固定的。
3在程序中所有的方法都是平行。
4方法的执行:必须在main方法中或者其他方法中调用:通过方法名称(传入所需参数)方 法如果没有在main或者其他方法中调用是不会执行的。
5方法不能嵌套方法但是方法可以调用方法
6.方法中参数的传递
当传递的是基本类型的数据的时候,值传递,传递的是变量的值
当传递的是引用类型的数据的时候,传递的是地址,址传递
本质都是值传递
方法的重载:(判断方法是否构成重载的判断依据)
1在同一个类中
2方法名称相同
3参数列表不同:
①参数的个数不同
②参数的类型不同
③参数列表有不同的类型构成,不同类型的顺序不同
注意:方法的返回值不能作为是否重载的依据
方法与数组
方法与数组
jdk5的新特性 可变参数
方法与数组
可以直接以可变参数作为方法的形参
当参数列表中存在可变参数的时候可变形参必须位于参数列表的末尾
可变参数只能传入同种类型的数据
可变参数也可构成重载
方法与数组
eclips的断点调试
可变参数和数组之间不构成重载
数组是引用类型
方法与数组
方法与数组
方法与数组
方法与数组

3.4 二维数组

1.二维数组的定义:
动态初始化
int [] [] arr = new int [5] [5];
int [] [] arr = new int [5] [];
静态初始化
int [] [] arr = new int [] [] {{1,2,3},{4,5,6},{7,8,9},{3,6,9}};
特殊形式
//数组定义的特殊形式
int [] x,y[];
x = new int [3];
y = new int [5] [];
二维数组的基本操作
方法与数组
方法与数组
方法与数组

3.5 数组中涉及的常见算法

  1. 数组元素的赋值(杨辉三角等)

  2. 求数值型数组中元素的最大值、最小值、平均数、总和等

  3. 数组的复制、反转、查找(线性查找、二分法查找)

  4. 数组元素的排序算法
    1 、二分法查找算法-----分治算法
    二分查找算法:在数组中查找指定的元素
    前提:数组必须是有序使用从小到大
    思想:
    key = 256
    -99,- 54,-2,0,2.33,43,256,999
    1 将数组从中间分开获取数组的中间位置
    2 使用key和中间位置的元素进行比对
    3如果要找元素比中间元素小意味着key存在前半部分
    4如果要找的元素比中间元素大意味着key在后半部分
    5如果key等于中间元素意味着找到目标元素
    //二分法查找:要求此数组必须是有序的。
    int[] arr3 = new int[]{-99,-54,-2,0,2,33,43,256,999};
    boolean isFlag = true;
    int number = 256;
    //int number = 25;
    int head = 0;//首索引位置
    int end = arr3.length - 1;//尾索引位置
    while(head <= end){
    int middle = (head + end) / 2;
    if(arr3[middle] == number){
    System.out.println(“找到指定的元素,索引为:” + middle);
    isFlag = false;
    break;
    }else if(arr3[middle] > number){
    end = middle - 1;
    }else{//arr3[middle] < number
    head = middle + 1;
    }
    }
    if(isFlag){
    System.out.println(“未找打指定的元素”);
    }

    2 、排序算法
    2.1 算法概述
    通常来说,排序的目的是快速查找。
    衡量排序算法的优劣:
    1.时间复杂度:分析关键字的比较次数和记录的移动次数
    2.空间复杂度:分析排序算法中需要多少辅助内存
    3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。
    排序算法分类:内部排序和外部排序。
    内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。
    外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
    十大内部排序算法
    选择排序 :直接选择排序、堆排序
    交换排序 :冒泡排序、快速排序
    插入排序 :直接插入排序、折半插入排序、Shell排序
    归并排序
    桶式排序
    基数排序
    2.2 算法的5大特征
    方法与数组
    2.3 冒泡排序
    介绍: 冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元 素,如果他们的顺序错误就把他们交换过来。
    排序思想:
    (1)比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
    (2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步 做完后,最后的元素会是最大的数。
    (3)针对所有的元素重复以上的步骤,除了最后一个。
    (4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要 比较为止。
    方法与数组
    public class BubbleSort {
    public static void main(String[] args) {
    int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
    //外层控制比较次数 n个元素 比较 n - 1
    //内存循环来控在每次比较时的相邻元素的比较和交换
    for(int i = arr.length-1 ; i > 0 ; i–) {//比较的次数时递减的
    for(int j = 0 ; j < i; j++) {//控制要比较的元素 元素的 个数是随着比较的次数变换的
    //比较相邻的两个元素
    if(arr[j] > arr[j + 1]) {//如果左边的大于右边 则需要交换两个元素的位置
    int temp = arr[j];
    arr[j] = arr[j + 1];
    arr[j + 1] = temp;
    }
    }
    }
    //遍历数组
    for(int i : arr) {
    System.out.println(i);
    }
    }
    }

    冒泡排序的改造
    **public class BubbleSort {

    public static void main(String[] args) {
    int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
    //外层控制比较次数 n个元素 比较 n - 1
    //内存循环来控在每次比较时的相邻元素的比较和交换
    bubbleSort(arr);

    }
    //冒泡排序
    public static void bubbleSort(int[] arr) {
    for(int i = arr.length-1 ; i > 0 ; i–) {//比较的次数时递减的
    for(int j = 0 ; j < i; j++) {//控制要比较的元素 元素的 个数是随着比较的次数变换的
    //比较相邻的两个元素
    if(arr[j] > arr[j + 1]) {//如果左边的大于右边 则需要交换两个元素的位置
    // int temp = arr[j];
    // arr[j] = arr[j + 1];
    // arr[j + 1] = temp;
    swap(arr,j,j+1);
    }
    }
    }
    printArr(arr);
    }
    //交换数组两个元素的位置
    public static void swap(int[] arr , int index1, int index2) {
    int temp = arr[index1];
    arr[index1] = arr[index2];
    arr[index2] = temp;
    }
    public static void printArr(int[] arr) {
    //遍历数组
    for(int i : arr) {
    System.out.println(i);
    }
    }
    }**
    递归
    **/

  • 递归的思想:在其中方法自己调自己 递归必须有一个结束
  • 求一个整数的阶乘 5! = 5 4321
  • 5! = 5 * 4!
  • 4! = 4* 3!
  • 3! = 3* 2!
  • 2! = 2 * 1!
  • 1! = 1 n! = n * (n-1)!
    /
    public class DiGui {
    public static void main(String[] args) {
    int n = 5;
    for(int i = 1 ; i <= n; i++) {
    System.out.println(“第” + i+“的阶乘为:”+jieCheng(i));
    }
    }
    public static int jieCheng(int n) {
    int chengji = 0;
    if(n == 1) {
    return 1;
    }
    chengji = n * jieCheng(n -1);//递归
    return chengji;
    }
    }

    2.4 快速排序
    方法与数组
    排序思想:
  1. 从数列中挑出一个元素,称为"基准"(pivot),

  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准 值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后, 该基准就处于数列的中间位置。这个称为分区(partition)操作。

  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数 列排序。

  4. 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好 了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代 (iteration)中,它至少会把一个元素摆到它最后的位置去。
    **public class QuickSort {
    public static void main(String[] args) {
    int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
    quickSort(arr);
    printArr(arr);

    //快速排序
    public static void quickSort(int[] arr) {
    if(arr.length <= 1) {
    return;
    }
    sort(arr,0,arr.length -1);//这是第一次
    }
    //核心算法
    public static void sort(int[] arr,int left ,int right) {
    if(left > right) {//对于传入的参数要判断 不能交叉越界
    return;
    }
    int base = arr[left];//基准元素
    int l = left;
    int r = right;
    while(l != r) {//只知道循环条件 而不知道循环的具体的情况 用while
    // 从右往左找
    while(arr[r] >= base && l < r) { //从右往左 while结束 就是找见比基准小的元素
    r–;
    }
    //从左往右找
    while(arr[l] <= base && l < r) {// while找到比基准大的
    l++;
    }
    if(l < r) {
    //交换位置
    int temp = arr[l];
    arr[l] = arr[r];
    arr[r] = temp;
    }
    }
    // base 归回 回到中间位置 此时位于base左边的都是比他小的 位于base右边都是比他大的
    arr[left] = arr[l];
    arr[l] = base;
    sort(arr,left,l-1);//对左半部分进行递归排序
    sort(arr,r+1,right);//右半部
    }
    public static void printArr(int[] arr) {
    //遍历数组
    for(int i : arr) {
    System.out.println(i);
    }
    }
    }**
    2.5 选择排序
    选择排序是一种简单直观的排序算法,工作原理为:在未排序的序列中找出最小(大)元素与第一个位置的元素交换位置
    注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
    算法简介:
    1.初始状态:序列为无序状态。
    2.第1次排序:从n个元素中找出最小(大)元素与第1个记录交换
    3.第2次排序:从n-1个元素中找出最小(大)元素与第2个记录交换
    4.第i次排序:从n-i+1个元素中找出最小(大)元素与第i个记录交换
    5.以此类推直到排序完成
    方法与数组
    public class SelectSort {
    public static void main(String[] args) {
    int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
    System.out.println(“原始数组:”);
    printArr(arr);
    for(int i = 0 ; i < arr.length ; i++){
    int minIndex = i;//minIndex 记录最小的元素所在的位置 假设每次开始的位置位最小元素
    for(int j = i ; j < arr.length; j++) {
    if(arr[minIndex] > arr[j]) {
    minIndex = j;
    }
    }
    int temp = arr[i];
    arr[i] = arr[minIndex];
    arr[minIndex] = temp;
    System.out.println(“第” + i+ “次 比较:”);
    printArr(arr);
    }
    System.out.println(“最终结果:”);
    printArr(arr);
    }
    public static void printArr(int[] arr) {
    //遍历数组
    for(int i : arr) {
    System.out.print(i +" “);
    }
    System.out.println();
    }
    }
    选择排序改造
    public class SelectSort {
    public static void main(String[] args) {
    int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
    System.out.println(“原始数组:”);
    printArr(arr);
    selectSort(arr);
    System.out.println(“最终结果:”);
    printArr(arr);
    }
    public static void selectSort(int[] arr) {
    for(int i = 0 ; i < arr.length ; i++){//控制比较的次数
    int minIndex = i;//minIndex 记录最小的元素所在的位置 假设每次开始的位置位最小元素
    for(int j = i ; j < arr.length; j++) {//控制元素之间比较
    if(arr[minIndex] > arr[j]) {
    minIndex = j;
    }
    }
    swap(arr, i, minIndex);
    System.out.println(“第” + i+ “次 比较:”);
    printArr(arr);
    }
    }
    //交换数组两个元素的位置
    public static void swap(int[] arr , int index1, int index2) {
    int temp = arr[index1];
    arr[index1] = arr[index2];
    arr[index2] = temp;
    }
    public static void printArr(int[] arr) {
    //遍历数组
    for(int i : arr) {
    System.out.print(i +” ");
    }
    System.out.println();
    }
    }
    2.6 插入排序(InsertSort)
    算法简介:
    1.从第一个元素开始,该元素可认为已排序。
    2.取出下一个元素,在排序好的元素序列中从后往前扫描
    3.如果元素(已排序)大于新元素,将该元素移到下一位置
    4.重复3.直到找到已排序的元素小于或等于新元素的位置
    5.将新元素插入该位置后
    6.重复2-5直到排序完成
    方法与数组
    public class InsertSort {
    public static void main(String[] args) {
    int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
    for(int i = 0 ; i < arr.length -1;i++) {
    for(int j = i + 1; j > 0 ; j-- ) {
    if(arr[j] < arr[j -1]) {
    int temp = arr[j];
    arr[j] = arr[j-1];
    arr[j - 1] = temp;
    }else {// 当后边的元素比前边的元素大或相等 不要交换 直接结束循环
    break;
    }
    }
    }
    for(int i : arr) {
    System.out.println(i);
    }
    }
    }
    2.7 排序算法性能对比方法与数组
    1.从平均时间而言:快速排序最佳。但在最坏情况下时间性能不如堆排序和归 并排序。
    2.从算法简单性看:由于直接选择排序、直接插入排序和冒泡排序的算法比较 简单,将其认为是简单算法。对于Shell排序、堆排序、快速排序和归并排序 算法,其算法比较复杂,认为是复杂排序。
    3.从稳定性看:直接插入排序、冒泡排序和归并排序时稳定的;而直接选择排 序、快速排序、 Shell排序和堆排序是不稳定排序
    4.从待排序的记录数n的大小看,n较小时,宜采用简单排序;而n较大时宜采 用改进排序。
    2.8 排序算法的选择
    (1)若n较小(如n≤50),可采用直接插入或直接选择排序。
    当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。
    (2)若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排 序为宜;
    (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或 归并排序。

3.6 Arrays工具类的使用

搜索
方法与数组
排序
方法与数组
数组的copy
方法与数组
将数组转化为字符串
方法与数组
public static void main(String[] args) {
int[] arr = new int[]{3,2,5,-1,12,-56,32,-24,11,5};
System.out.println(“调用sort前:”);
printArr(arr);
//Arrays.sort(arr,3,7);//半开半闭区间 包含开始索引不包含结束索引
Arrays.sort(arr);//排序
System.out.println(“调用sort后:”);
printArr(arr);
int index = Arrays.binarySearch(arr, -32);//搜索
System.out.println(index);
// 数组的copy copy指定个数个元素 从0开始
int[] arrCopy = Arrays.copyOf(arr, 3);
printArr(arrCopy);
//数组的copyt copy的是指定范围
int[] arrCopyRange = Arrays.copyOfRange(arr, 3, 7);//左闭右开区间
printArr(arrCopyRange);
//将一个数组转换位字符串
String arrStr = Arrays.toString(arr);
System.out.println(arrStr);
}
数组使用中两个创建问题
1 数组下标越界 IndexOutOfBoundsException
使用的数组的下标超出了数组下标的范围
数组线标的范围0 — arr.length -1
2 空指针异常 NullPointException
int[] arr = null;//数组arr引用没有指向任何的对象
arr[0]// NullPointException

相关文章:

  • 2022-12-23
  • 2021-12-31
  • 2022-12-23
  • 2021-05-23
  • 2022-01-08
  • 2021-07-20
  • 2022-12-23
猜你喜欢
  • 2021-10-27
  • 2021-12-03
  • 2021-11-23
  • 2021-11-23
  • 2021-05-31
  • 2021-04-06
  • 2022-12-23
相关资源
相似解决方案