数组
1.数组的概念及定义
数组主要用于解决大量数字计算与存储的问题
比如:输入一百个数字统计其中的最大值和最小数并计算平均值
数组是Java提供的一种最简单的数据结构,可以用来存储一个元素个数固定,且类型相同的有序集。
数组在内存中的情况
栈:主要用于运行函数的内存
堆:主要用于存储数据对象的内存
每一个数组而言都是存在堆内存当中,每一个数组都是一个对象
数组的特点
数组本质上就是在堆内存中一系列地址连续且空间大小相等的存储空间(变量),每一个存储空间用来存储数据(基本数据类型,引用数据类型)
数组是在堆内存中存储,称之为是一个对数对象,并且在堆内存中存储的数据都有默认初始化的流程。所以数组创建之初,每一个存储空间里面都会呗JVM初始化该数据类型对应的零值。
数组的地址是连续的,所以通过公式:An=A1+(n-1)*d可以快速访问到其他的元素,所以对于数组而言,查找元素比较快。将元素的真实物理地址转换成对应的角标获取元素。
如何来调用数组?通过一个变量存储在该数组堆内存当中的首元素的地址。
当数组一旦定义出来,其长度不可变,存储空间的内容是可变的。
所以在定义数组的时候,要么把长度固定,要么直接输入相关元素。
数组的定义方式
//创建一个指定长度且指定数据类型的一维数组,名称为数组名,虽然没有指定元素,但是会有默认值
数据类型[] 数组名 = new 数据类型[长度];
//创建一个指定元素且指定数据类型的一维数组,名称为数组名,虽然有指定元素,但还是有默认初始化的步骤
数据类型[] 数组名 = new 数据类型[]{数据1,数据2,...,数据n};
数据类型[] 数组名 = {数据1,数据2,...,数据n};
public class Test{
public static void main(String[] args){
int[] arr = new int[5];
System.out.println(arr[0]);
//System.out.println(arr[5]);//ArrayIndexOutOfBoundsException: 5//数组角标越界
arr[2] = 10;
int[] arr2 = arr;
System.out.println(arr2[2]);
arr2 = null;
//System.out.println(arr2[2]);//NullPointerException空指针异常,已经为null不能引用
arr = null;
}
}
2.常用数组操作
数组遍历问题
public class Test{
public static void main(String[] args){
int[] arr = new int[]{1,2,3,4,5,6,7,8,9};
//String str str.length() ——通过函数获取长度
//int[] arr arr.length() ——通过属性获取长度
//通过角标遍历 可以在遍历过程中对指定元素进行修改
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
//foreach遍历 主要是针对一些可迭代对象 Iterable
/*
for(数据类型 变量名:可迭代容器){
}
*/
for(int num : arr){
//num -> arr[i] num的值是动态变化的
System.out.println(num);
}
//这种遍历方法只能获取元素,不能修改元素
}
}
数组最值问题
public class Test {
public static void main(String[] args){
int[] arr = new int[]{3,6,8,2,9,4,5,1,7};
int min = arr[0];
int max = arr[0];
for(int i = 1;i < arr.length;i++){
if(arr[i] < min){
min = arr[i];
}
if(arr[i] > max){
max = arr[i];
}
}
System.out.println("最大值" + max + "最小值" + min);
}
}
数组扩容问题
public class Test {
public static void main(String[] args){
int[] arr = new int[]{1,2,3,4,5};
arr = add(arr,6);
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
}
//在指定数组arr中添加指定元素element
public static int[] add(int[] arr,int element){
int[] newArr = new int[arr.length + 1];
for(int i = 0;i < arr.length;i++){
newArr[i] = arr[i];
}
newArr[newArr.length - 1] = element;
return newArr;
}
}
选择排序算法
public class Test {
public static void main(String[] args){
int[] arr = {8, 5, 6, 1, 4, 7, 9, 2, 3};
for (int i = 0; i < arr.length - 1; i++) {//-1指的是n个数字没有第n轮比较
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]){
swap(arr,i,j);
}
}
}
print(arr);
}
public static void print(int[] arr){
System.out.print("[");
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]);
if(i == arr.length - 1){
System.out.print("]");
}else{
System.out.print(",");
}
}
}
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
冒泡排序算法
public class Test {
public static void main(String[] args){
int[] arr = {8, 5, 6, 1, 4, 7, 9, 2, 3};
for(int i = 0;i <arr.length - 1;i++){//-1表示n个数字只有n-1轮
for(int j = 0;j < arr.length - 1 -i;j++){
if(arr[j] > arr[j + 1]){
swap(arr,j, j + 1);
}
}
}
print(arr);
}
public static void print(int[] arr){
System.out.print("[");
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]);
if(i == arr.length - 1){
System.out.print("]");
}else{
System.out.print(",");
}
}
}
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
插入排序算法
public class Test {
public static void main(String[] args){
int[] arr = {8, 5, 6, 1, 4, 7, 9, 2, 3};
for(int i = 1;i < arr.length;i++){
int e = arr[i];
int j = 0;
for(j = i;j > 0 && arr[j - 1] > e;j--){
arr[j] = arr[j - 1];
}
arr[j] = e ;
}
print(arr);
}
public static void print(int[] arr){
System.out.print("[");
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]);
if(i == arr.length - 1){
System.out.print("]");
}else{
System.out.print(",");
}
}
}
}
计数排序算法
public class Test{
public static void main(String[] args){
int[] arr = {-2,9,8,6,4,12,3,8,4,9,13,-3,-1,-3};
int max = arr[0];
int min = arr[0];
for(int i = 0;i < arr.length;i++){
if(arr[i] < min){
min = arr[i];
}
if(arr[i] > max){
max = arr[i];
}
}
int[] temp = new int[max - min + 1];
//对应关系 index = number - min number = index + min number指原数组数据,index指新数组角标
//统计遍历原数组
for(int i = 0;i < arr.length;i++){
temp[arr[i] - min]++;
}
//temp[index] 表示index对应的数字number出现的次数
int k = 0;//为打印原数组设置的新角标
for(int index = 0;index < temp.length;index++){
while(temp[index] != 0){
arr[k] = min + index;
k++;
temp[index]--;
}
}
print(arr);
}
public static void print(int[] arr){
System.out.print("[");
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]);
if(i == arr.length - 1){
System.out.print("]");
}else{
System.out.print(",");
}
}
}
}
基数排序算法
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
int[] arr = {155, 254, 6, 94, 5, 3, 8, 10, 59};
//1.先找到最大值 决定轮数
int max = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int radex = (max +"").length();//最大数的位数
//2.创建十个桶 每一个桶是LinkedList
LinkedList<Integer>[] queues = new LinkedList[10];
for (int i = 0; i < queues.length; i++) {
queues[i] = new LinkedList<Integer>();
}
//3.进行数字分类和规整问题
//r=0表示个位 r=1表示十位 r=2表示百位
for (int r = 0; r < radex; r++) {
for (int i = 0; i < arr.length; i++) {
int index = getIndex(arr[i], r);//获取数字的r位返回该数字要去的桶的角标
queues[index].offer(arr[i]);//入队 queues[index]桶的角标
}
//重新规整到arr里
int k = 0;
for (int index = 0; index < queues.length; index++) {
while (!queues[index].isEmpty()) {
arr[k] = queues[index].poll();//出队列并规整到arr里
k++;
}
}
}
print(arr);
}
public static int getIndex(int number,int r){
//123 r=0
//123 r=1
//123 r=2
int index = 0;
for(int i= 0;i <= r;i++){
index = number % 10;
number /= 10;
}
return index;
}
public static void print(int[] arr){
System.out.print("[");
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]);
if(i == arr.length - 1){
System.out.print("]");
}else{
System.out.print(",");
}
}
}
}
二分查找算法
有一个前提,所查找的数据集必须是有序的(升序,降序)
public class Test{
public static void main(String[] args){
int[] arr = {1,2,3,4,5,6,7,8,9};
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
int key = 10;
while(arr[mid] != key){
if(key < arr[mid]){
max = mid - 1;
}
if(arr[mid] < key){
min = mid + 1;
}
if(min > max){
mid = -1;
break;
}
mid = (min + max) / 2;
}
System.out.println(mid);
}
}
可变长参数列表
public class Test {
public static void main(String[] args) {
show(1);
show(1,2,3);
show("hehe");
show("haha","lala","xixi");
}
public static void show(int ... nums){
for(int i = 0;i < nums.length;i++){
System.out.print( nums[i]+" ");
}
System.out.println();
}
public static void show(String ... strs){
for(int i = 0;i < strs.length;i++){
System.out.print( strs[i]+" ");
}
System.out.println();
}
}
3.二维数组
二维数组,在表现形式上就是一个表格,在操作表格的时候以行列来操作
所谓的二维数组本质上就是一个一维数组,只不过该一维数组里面的元素是另一个一维数组而已
一个4×5的二维数组,一共有几个一维数组组成? 答:5个
二维数组的定义
public class Test{
public static void main(String[] args){
//数据类型[][] 矩阵名 = new 数据类型[row][col];
int[][] matrix = new int[2][3];
//数据类型[][] 矩阵名 = new 数据类型 {{...},{...}.{...}};
//数据类型[][] 矩阵名 = {{...},{...}.{...}};
int[][] matrix2 ={
{1,2,3},
{4,5,6},
{7,8,9}
};
for(int i = 0;i < matrix2.length;i++){//矩阵的行
for(int j = 0;j < matrix2[i].length;j++){//矩阵的列
System.out.print(matrix2[i][j] + " ");
}
System.out.println();
}
int[][] matrix3 = {//锯齿矩阵
{1},
{1,2,3},
{1,2,3,4},
{1,2,3,4,5}
};
for(int i = 0;i < matrix3.length;i++){
for(int j = 0;j < matrix3[i].length;j++){
System.out.print(matrix3[i][j] + " ");
}
System.out.println();
}
}
}
输入8个点坐标,然后计算这些点中,哪两个点的坐标是最近的?
import java.util.Scanner;
public class Test{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
double[][] points = new double[8][2];
//1.获取输入点的坐标
for(int i = 0;i < points.length;i++){
System.out.println("请输入第"+ (i + 1) + "个点坐标");
points[i][0] = input.nextDouble();
points[i][1] = input.nextDouble();
}
double shortestDistance = getDistance(points,0,1);
int p1 = 0;
int p2 = 0;
//求最短距离用选择排序算法
for(int i = 0;i < points.length - 1;i++){
for(int j = i + 1;j < points.length;j++){
double distance = getDistance(points,i,j);
if(distance < shortestDistance) {
shortestDistance = distance;
p1 = i;
p2 = j;
}
}
}
System.out.printf("(%.1f%,.1f)和(%.1f,%.1f)的最短距离为%.1f",points[p1][0],points[p1][1],points[p2][0],points[p2][1],shortestDistance);
}
public static double getDistance(double[][] m,int p1,int p2){
return Math.hypot(m[p1][0]-m[p2][0],m[p1][1]-m[p2][1]);
}
}
j);
if(distance < shortestDistance) {
shortestDistance = distance;
p1 = i;
p2 = j;
}
}
}
System.out.printf("(%.1f%,.1f)和(%.1f,%.1f)的最短距离为%.1f",points[p1][0],points[p1][1],points[p2][0],points[p2][1],shortestDistance);
}
public static double getDistance(double[][] m,int p1,int p2){
return Math.hypot(m[p1][0]-m[p2][0],m[p1][1]-m[p2][1]);
}
}