JavaSE基础:数组和排序算法

it2022-05-05  187

感谢尚硅谷免费的视频

声明和使用数组

分类存放不同类型的数据

数组是多个相同类型数据的组合,实现对这些数据的统一管理 数组中的元素可以是任何数据类型,包括基本类型和引用类型 数组属引用类型,数组型数据是对象(object),数组中的每个元素相当于该对象的成员变量

数组在内存中的存储

Int[] score={5,6,7,77,5}; 一维数组的声明方式:

type var[] 或 type[] var;

例如:

int a[]; int[] a1; double b[]; Mydate[] c; //对象数组

Java语言中声明数组时不能指定其长度(数组中元素的数), 例如:

int a[5]; //非法

动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行

int[] arr = new int[3]; arr[0] = 3; arr[1] = 9; arr[2] = 8;

静态初始化:在定义数组的同时就为数组元素分配空间并赋值。

int a[] = new int[]{ 3, 9, 8}; int[] a = {3,9,8};

Java中使用关键字new创建数组对象 创建基本数据类型一维数组对象 创建基本数据类型一维数组对象

编译时,不报错!!

数组脚标越界异常(ArrayIndexOutOfBoundsException)

int[] arr = new int[2]; System.out.println(arr[2]); 访问到了数组中的不存在的脚标时发生。

空指针异常(NullPointerException)

int[] arr = null; System.out.println(arr[0]); arr引用没有指向实体,却在操作实体中的元素时。

每次比较相邻两数 小的交换到前面 每轮结束后最大的数交换到最后

如何用二重循环将5个数字排序?N = 5

5个数字存放在一维数组中 外层循环控制比较多少轮,循环变量 i 内层循环控制每轮比较多少次,循环变量 j 代码框架 for (i = 0; i < N-1 ; i++)

{ for (j = 0; j < N-1-i ; j++) { // 比较 j 和 j+1 位置的元素 // 如果前大后小就交换 } }

冒泡排序速记口诀(升序):

N 个数字来排队 两两相比小靠前 外层循环 N-1 内层循环 N-1-i

数组排序

java.util.Arrays类的sort()方法提供了数组元素排序功能:

import java.util.*; public class Sort { public static void main(String[] args) { int [] number = {5,900,1,5,77,30,64,700}; Arrays.sort(number); for(int i = 0; i < number.length; i++) System.out.println(number[i]); } }

排序分类 插入排序

直接插入排序、折半插入排序、Shell排序

交换排序

冒泡排序、快速排序(或分区交换排序)

选择排序

简单选择排序、堆排序

归并排序 基数排序

排序方法的选择

(1)若n较小(如n≤50),可采用直接插入或直接选择排序。

当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。

(2)若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜; (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。

操作数组的工具类:Arrays

java.util.Arrays类包含了用来操作数组(比如排序和搜索)的各种方法。Arrays拥有一组static方法。

equals():比较两个array是否相等。array拥有相同元素个数,且所有对应元素两两相等。 fill():将值填入array中。 sort():用来对array进行排序。 binarySearch():在排好序的array中寻找元素。 另::array的复制。 System.arraycopy()

二维数组[][]:数组中的数组

格式1(动态初始化):int[][] arr = new int[3][2]; int[] n = new int[3];

定义了名称为arr的二维数组 二维数组中有3个一维数组 每一个一维数组中有2个元素 一维数组的名称分别为arr[0], arr[1], arr[2] 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;

格式2(动态初始化):int[][] arr = new int[3][];

二维数组中有3个一维数组。 每个一维数组都是默认初始化值null (注意:区别于格式1) 可以对这个三个一维数组分别进行初始化 arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2]; 注: int[][]arr = new int[][3]; //非法

Int[][] nums = new int[3][2]

想访问某个具体元素,则可以通过 :

数组名[行下标][列下标]

比如:Nums[1][0]

Nums.length: 3。二维数组的长度=一维数组的个数=行数 Num[0].length :2. 第一个一维数组的长度

数组的特点和好处

概念

数组:其实就是一个容器,和变量很像。变量只能保存一个数,而数组可以保存一组数.

好处

1、同时开辟多个空间,语句更加简洁,且提高效率 2、分类存储,而且数组中的空间都是连续的,所以查找比较方便

特点

1、数组是多个相同类型数据的组合,实现对这些数据的统一管理 2、数组中的元素可以是任何数据类型,包括基本类型和引用类型 3、数组属引用类型,数组型数据是对象(object),数组中的每个元素相当于该对象的成员变量 数组名又称为对象名或引用名 注意:引用类型的变量名(也叫对象名)存放在栈中,值(也叫对象)存放在堆中! 基本类型的变量名和值都存放在栈中

数组的四要素

1、数组类型 2、数组名(对象名或引用) 3、数组元素(多个) 4、下标(从0开始,到数组的长度-1) 访问数组的元素,不是仅仅通过数组名,而是通过数组名+下标 语法:score[下标]

数组的使用步骤

数组的动态初始化

1、声明 数据类型[] 数组名;或 数据类型 数组名[]; 2、开辟空间 数组名 = new 数据类型[长度];//长度必不可少 3、手动赋值 数组名[下标] = 值; 4、使用(打印、运算、判断等) System.out.println(数组名[下标]);

注意事项:

①数组的元素如果不赋值,也有默认值 int 0 double 0.0 char \u0000 boolean false 引用类型 null ②访问数组的元素时,下标必须在0——长度-1 的范围内,否则报数组下标越界的异常 ③数组的长度,可以通过 数组名.length表示,提高代码的维护性 ④数组的赋值和使用,往往可以通过搭配for循环一起操作 for(int i=0;i<数组名.length;i++){ //每一个元素表示为:数组名[i] }

案例:

求一个班级10名同学的平均分

数组的静态初始化

步骤1:声明并初始化 语法:数据类型[] 数组名 = new 数据类型[]{值,值,值}; 或 数据类型[] 数组名 = {值,值,值}; int[] arr = {3,4,5,6,100}; //int[] arr2 = new int[] {3,4,5,6,100}; 步骤2:使用 for(int i=0;i<数组名.length;i++){ //每一个元素表示为:数组名[i] }

基本类型的赋值:

int a = 10; int b = a;//赋值

引用类型的赋值:

int[] arr1={1,2,3}; int[] arr2=arr1;//赋值

特点:

基本类型的赋值,赋的是值(内容),其中一个变量对其更改不影响另外一个 引用类型的赋值,赋的是地址,两个引用共同指向一个地址(对象),所以其中一个引用对其更改影响另外一个 注意:如果希望引用类型赋值时,只赋内容,则可以使用循环赋值的方式,

语法:

int[] array2 = new int[array1.length]; for(int i=0;i<array2.length;i++){ array2[i] = array1[i]; }

数组的反转 方式一:

for(int i=0;i<arr.length/2;i++){ //交换两个数 i vs arr.length-1-i int temp = arr[i]; arr[i] = arr[arr.length-1-i]; arr[arr.length-1-i] = temp; }

方式二:

//①创建一个新数组,长度=arr.length int[] newArr = new int[arr.length]; //②逆序赋值 /* i 0 arr.length-1 1 arr.length-2 */ for(int i=0,j=arr.length-1;i<arr.length;i++,j--){ newArr[j]=arr[i]; } //③将新数组的地址赋值给arr arr=newArr;

数组的高级使用

数组的添加

//----------------具体的添加业务---------- //①新建一个数组,长度=arr.length+1 int[] newArr = new int[arr.length+1]; //②依次为新数组的元素赋值 for(int i=0;i<arr.length;i++){ newArr[i] = arr[i]; } //③将add赋值到新数组的空位上 newArr[newArr.length-1] = add; //④将newArr的地址赋值给arr arr = newArr; System.out.println("添加成功!");

数组的插入

//----------------------具体的插入业务----------- //①创建新数组,长度=arr.length+1 int[] newArr = new int[arr.length+1]; //②循环赋值 for(int i=0;i<arr.length;i++){ newArr[i] = arr[i]; } //③循环后移 for(int i=newArr.length-1;i>index;i--){ newArr[i]=newArr[i-1]; } //④将新元素赋值到index位置上 newArr[index] = add; //⑤将newArr的地址赋值给arr arr = newArr; System.out.println("插入成功!");

二维数组

理解 二维数组其实就是 一维数组的组合,也就是一维数组的定义类型又为一维数组

int[][] num; int[] num[]; int num[][];

使用步骤

方式一:动态初始化

1.声明

数据类型[][] 数组名;或 数据类型 数组名[][]; 数据类型[] 数组名[];

2.开辟空间

情况1:固定列数 数组名 = new 数据类型[行数][列数]; 情况2:不固定列数 数组名 = new 数类型[行数][];

3.赋值

情况1:固定列数 for(int i=0;i<nums.length;i++){//i:行数 for(int j=0;j<nums[i].length;j++){//j:列数 nums[i][j]=值; } } 情况2:不固定列数 for(int i=0;i<nums.length;i++){//i:行数 nums[i]=new 数据类型[长度]; for(int j=0;j<nums[i].length;j++){//j:列数 nums[i][j]=值; } } 4.使用(打印、求和、最值) for(int i=0;i<nums.length;i++){//i:行数 for(int j=0;j<nums[i].length;j++){//j:列数 System.out.print(nums[i][j]); } }

方式二:静态初始化

1.声明并初始化

数据类型[][] 数组名={{},{},{}}; 或 数据类型[][] 数组名=new 数据类型[][]{{},{},{}};

2.使用(打印、求和、最值)

for(int i=0;i<nums.length;i++){//i:行数 for(int j=0;j<nums[i].length;j++){//j:列数 System.out.print(nums[i][j]); } }

int[][][] nums; int[][][][] nums; 排序

假设含有n个记录的序列为{R1,R2,...,Rn},其相应的关键字序列为{K1,K2,...,Kn}。将这些记录重新排序为{Ri1,Ri2,...,Rin},使得相应的关键字值满足条Ki1<=Ki2<=...<=Kin,这样的一种操作称为排序。

通常来说,排序的目的是快速查找。 衡量排序算法的优劣:

1.时间复杂度:分析关键字的比较次数和记录的移动次数 2.空间复杂度:分析排序算法中需要多少辅助内存 3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。

排序算法分类:内部排序和外部排序。

内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。

选择排序

基本原理

将待排序的元素分为已排序(初始为空)和未排序两组,依次将未排序的元素中值最小的元素放入已排序的组中。 直接选择排序简单直观,但性能略差;堆排序是一种较为高效的选择排序方法,但实现起来略微复杂

直接选择排序

直接选择排序的基本过程为:

直接选择排序效率分析 算法的时间效率

无论初始状态如何,在第i趟排序中选择最小关键码的元素,需做n-i次比较,因此总的比较次数为:

算法的空间效率

空间效率很高,只需要一个附加程序单元用于交换,其空间效率为

算法的稳定性

不稳定

堆排序

若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。 最小化堆,也称为小顶堆;最大化堆,也称为大顶堆。


最新回复(0)