JavaSE基础:数组和排序算法

在这里插入图片描述
感谢尚硅谷免费的视频

声明和使用数组

分类存放不同类型的数据
在这里插入图片描述

数组是多个相同类型数据的组合,实现对这些数据的统一管理
数组中的元素可以是任何数据类型,包括基本类型和引用类型
数组属引用类型,数组型数据是对象(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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值