IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数组(java) -> 正文阅读

[数据结构与算法]数组(java)

数组习题的引入

import java.util.*;
public class TestArray01{
	public static  void main(String[] args){
		//功能:键盘录入十个学生的成绩,求和,求平均数
		//定义一个求和的变量
		int sum = 0;
		Scanner sc = new Scanner(System.in);
		for(int i = 1;i<=10;i++){//i:控制循环的次数
			System.out.println("请录入第"+i+"个学生的成绩");
			int score = sc.nextInt();
			sum += score;
		}
	
		System.out.println("十个学生的成绩之和为:"+sum);
		System.out.println("十个学生的成绩平均数为:"+sum/10);
		
		
		
		
		//缺点:求某个学生的成绩?  -----》不能
	
	
	}
	
}

缺点:不能求每个学生的具体成绩是多少

解决:将成绩进行存储? -----》引入:数组

感受到数组的作用:数组用来存储数据的,在程序设计中,为了方便处理,数组用来将相同类型的若干数据组织起来。这个若干数据的集合我们称之为:数组。

1.数组的学习

【1】数组的定义

数组是相同类型的数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每个数据称作一个元素,每个元素可以通过一个索引(下标)来访问他们。

数组的四个基本特点:

(1)长度是确定的。数组一旦被创建,它的大小就是不可以改变的。

(2)其元素的类型必须是相同类型,不允许出现混合类型。

(3)数组的类型可以是任何数据类型,包括基本类型和引用类型。

(4)数组有索引的:索引从0开始,到数组 length-1 结束

(5)数组变量属于引用类型,数组也是对象

ps:数组变量属于引用类型,数组也是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,java中对象是在堆中的,因此数据无论保存原始类型还是其他对象类型,数据对象本身是在堆中存储的。

【2】数组的学习

public class TestArray02{
	public static  void main(String[] args){
		//数组的作用:用来存储相同类型的数据
		//以int类型的数据为案例:数组用来存储int类型的数据
		//1.声明(定义数组)
		int[] arr;//定义一个int类型的数组,名字叫arr
		int arr2[];
		//如果数组只声明,没有后续操作,那么这个数组相当于没有定义
		int arr3[] = null;// 空 辨别:数组赋值为null和什么都没有赋值,不一样的效果
		
		//2.创建
		arr = new int[4];//给数组开一个长度为4的空间
		//编译期声明和创建会被合为一句话:int[] arr = new int[4];
		
		//3.赋值
		arr[0] = 11;
		arr[3] = 13;
		arr[2] = 44;
		arr[1] = 55;
		
		/*
		arr[4] = 77;
		出现异常:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
		Array  数组
		Index  索引
		OutOf  超出
		Bounds  界限
		Exception  异常
		----》数据索引越界异常
		
		*/
		//4.使用
		System.out.println(arr[2]);
		System.out.println(arr[0]+100);
		//通过一个数组属性来获取  length 长度
		System.out.println("数组的长度是:"+arr.length);
		
	}
}

(内存分析)

2.数组的遍历

import java.util.*;
public class TestArray03{
	public static  void main(String[] args){
		//功能:键盘录入十个学生的成绩,求和,求平均数
		//定义一个int类型的数组,长度为10;
		int[] scores = new int[10];
		//定义一个求和的变量
		int sum = 0;
		Scanner sc = new Scanner(System.in);
		
		for(int i = 1;i<=10;i++){//i:控制循环的次数
			System.out.println("请录入第"+i+"个学生的成绩");
			int score = sc.nextInt();
			scores[i-1] = score;
			sum += score;
		}
	
		System.out.println("十个学生的成绩之和为:"+sum);
		System.out.println("十个学生的成绩平均数为:"+sum/10);
		
		
		
		
		//求全部学生的成绩:
		//将数组中的每个元素进行查看  ---->数组的遍历:
		//方式一:普通for循环  -----》正向遍历
		for(int i = 0;i<=9;i++){
			System.out.println("第"+(i+1)+"个学生的成绩为"+scores[i]);
		}
		
			//方式二:增强for循环
			//对 scores数组进行遍历,遍历出来的每一个元素都用int类型的num接收
			for(int num:scores){
				//每次都将num在控制台输出
				System.out.println(num);
			}
			
			
			/*
			增强for循环:
			优点:代码简单
			缺点:单纯的增强for循环不能设计和索引相关的操作
			*/
			
			
			//方式三:利用普通for循环;逆向遍历
			for(int i=9;i>=0;i--){
				System.out.println("第"+(i+1)+"个学生的成绩为"+scores[i]);
			}
		}
	
	}

3.数组的初始化方式

【1】静态初始化

除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

eg:

int[] arr = {12,23,45};

int[] arr = new int[] {12,23,45};

注意:

(1).new int[3]{12,23,45};? ----->错误(自动默认分配三个空间,不用写三个长度)

(2).int[] arr;

arr = {12,23,45}? ?------>错误 (这么写编译器不认为这是一个数组)

【2】动态初始化

数组定义与数组元素分配空间并复制的的操作分开进行。

eg:

int[] arr = new int[3];

arr[0] = 12;

arr[1] = 23;

arr[2] = 45;

【3】默认初始化

数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

eg:

int[] arr = new int[3];? ----->数组有默认的初始化值

4.数组的应用

1)最值问题

【1】实现一个功能:给定一个数组int[] arr = {12,23,34,45,56,67,1,4}; 求出数组中的最大数?。

(原理:打擂原理)

public class TestArray04{
	public static  void main(String[] args){
		//实现一个功能:给定一个数组int[] arr = {12,23,34,45,56,67,1,4}
		//1.给定一个数组
		int[] arr = {12,23,34,45,56,67,1,4};
		
		//2.求出数组中的最大值
		//先找一个数上擂台,假定认为这个数最大
		int maxNum = arr[0];
		for(int i = 0;i<arr.length;i++){
			if(arr[i]>maxNum){
				maxNum = arr[i];
			}
		}
		System.out.println("当前数组中最大的数为:"+maxNum);
		
	}
}

【2】将求最大值的方法提取出来

public class TestArray05{
	public static  void main(String[] args){
		//实现一个功能:给定一个数组int[] arr = {12,23,34,45,56,67,1,4}
		//1.给定一个数组
		int[] arr = {12,23,34,45,56,67,1,4};
		
		//2.求出数组中的最大值
		//调用方法:
		int num = getMaxNum(arr);
		System.out.println("当前数组中最大的数为:"+num);
	}
	
	
	/*
	想提取一个方法:求数组中的最大值
	求哪个数组中的最大值 ----》不确定因素:哪个数组(形参) ---》返回值:最大值
	*/
	public static int getMaxNum(int[] arr){
		//先找一个数上擂台,假定认为这个数最大
		int maxNum = arr[0];
		for(int i = 0;i<arr.length;i++){
			if(arr[i]>maxNum){
				maxNum = arr[i];
			}
		}
		return maxNum;
	}
}

【3】画内存

方法的实参传递给形参的时候一定要注意:一切都是值传递

如果是基本数据类型,那么传递的就是字面值

如果是引用数据类型,那么传递的就是地址值

2)查询问题

【1】查询指定位置的元素

public class TestArray06{
	public static  void main(String[] args){
		//查询指定位置的元素
		//给定一个数组:
		int[] arr = {12,23,34,45,3,4,6};
		//查找索引位置为2的元素的位置
		System.out.println(arr[2]);
	}
}

上面的代码体现了数组的一个优点:

在按照位置查询的时候,直接一步到位,效率非常高

?【2】查找指定元素的位置? ------》找出元素对应的索引

public class TestArray07{
	public static  void main(String[] args){
		//查找指定元素的位置 ---》找出元素对应的索引
		//给定一个数组:
		int[] arr = {12,23,34,4,3,4554,34,3};
		//            0  1  2 3 4  5   6 7
		
		//功能:查询元素34对应的索引
		int index = -1;//这个初始值只要不是数组的索引即可
		for(int i=0;i<arr.length;i++){
			if(arr[i]==34){
				index = i;//只要找到了元素,那么index就变为i
				break;//只要找到了这个元素,循环停止
			}
		}
		if(index!=-1){
			System.out.println("元素对应位置的索引为"+index);
		}else{//index==-1
		System.out.println("查无此数!");
		}
	}
}

【3】将查询指定元素对应的索引的功能提取为方法

public class TestArray08{
	public static  void main(String[] args){
		//查找指定元素的位置 ---》找出元素对应的索引
		//给定一个数组:
		int[] arr = {12,23,34,4,3,4554,34,3};
		//            0  1  2 3 4  5   6 7
		
		//功能:查询元素34对应的索引
		//调用方法
		int index = getIndex(arr,34);
		//后续对index的值进行一个判断
		if(index!=-1){
			System.out.println("元素对应位置的索引为"+index);
		}else{//index==-1
		System.out.println("查无此数!");
		}
	}
	
	/*
	定义一个方法:查询数组中指定元素对应的索引;
	不确定因素:哪个数组,那个指定元素  (形参)
	返回值:索引
	*/
	
	public static int getIndex(int[] arr,int ele){
		int index = -1;//这个初始值只要不是数组的索引即可
		for(int i=0;i<arr.length;i++){
			if(arr[i]==ele){
				index = i;//只要找到了元素,那么index就变为i
				break;//只要找到了这个元素,循环停止
			}
		}
		return index;
	}
	
}

3)添加元素

【1】实现一个功能:在数组下标为2的位置添加一个元素

添加逻辑:

?

public class TestArray09{
	public static  void main(String[] args){
		//功能:给定一个数组,在数组下标为2的位置上添加一个元素55
		
		//1.给定一个数组
		int[] arr = {12,23,44,67,76,89,22,2,3,35,455,6};
		//            0  1  2  3  4  5  6 7 8  9  10 11
		//2.输出增加元素前的数组
		System.out.print("增加元素前的数组:");
		for(int i=0;i<arr.length;i++){
			if(i!=arr.length-1){
				System.out.print(arr[i]+",");
			}else{//i==arr.length-1  最后一个元素不用加逗号
				System.out.print(arr[i]);
			}
		}
		
		//3.增加元素
		/*
		arr[6] = arr[5];
		arr[5] = arr[4];
		arr[4] = arr[3];
		arr[3] = arr[2];
		arr[2] = 91;
		*/
		int index = 2;//在指定位置添加元素
		for(int i=arr.length-1;i>=(index+1);i--){
			arr[i] = arr[i-1];
		}
		arr[index] = 91;
		//4.输出增加元素后的数组
		System.out.print("\n增加元素后的数组:");
		for(int i=0;i<arr.length;i++){
			if(i!=arr.length-1){
				System.out.print(arr[i]+",");
			}else{
				System.out.print(arr[i]);
			}
		}
		
		
	}
}

【2】将添加功能提取为一个方法

import java.util.*;
public class TestArray10{
	public static  void main(String[] args){
		//功能:给定一个数组,在数组下标为2的位置上添加一个元素55
		
		//1.给定一个数组
		int[] arr = {12,23,44,67,76,89,22,2,3,35,455,6};
		//            0  1  2  3  4  5  6 7 8  9  10 11
		//2.输出增加元素前的数组
		System.out.print("增加元素前的数组:");
		for(int i=0;i<arr.length;i++){
			if(i!=arr.length-1){
				System.out.print(arr[i]+",");
			}else{//i==arr.length-1  最后一个元素不用加逗号
				System.out.print(arr[i]);
			}
		}
		
		//从键盘录入数据
		Scanner sc = new Scanner(System.in);
		System.out.println("\n请录入你要添加元素的指定下标");
		int index = sc.nextInt();
		System.out.println("\n请录入你要添加的元素");
		int ele = sc.nextInt();
		
		//3.增加元素
		/*
		arr[6] = arr[5];
		arr[5] = arr[4];
		arr[4] = arr[3];
		arr[3] = arr[2];
		arr[2] = 91;
		*/
		//调用方法
		insertEle(arr,index,ele);
		
		
		//4.输出增加元素后的数组
		System.out.print("\n增加元素后的数组:");
		for(int i=0;i<arr.length;i++){
			if(i!=arr.length-1){
				System.out.print(arr[i]+",");
			}else{
				System.out.print(arr[i]);
			}
		}
	}

/*
	提取一个添加元素的方法:
	在数组的指定位置上添加一个指定的元素
	在哪个数组的哪个位置添加哪个元素!
	(不确定因素:形参:哪个数组,哪个位置,哪个元素,)
	返回值:无
	*/
	public static void insertEle(int[] arr,int index,int ele){
		for(int i=arr.length-1;i>=(index+1);i--){
			arr[i] = arr[i-1];
		}
		arr[index] = ele;
	}
}

4)删除元素

逻辑

import java.util.*;
public class TestArray11{
	public static  void main(String[] args){
		//功能:给定一个数组,删除下标为2元素
		
		//1.给定一个数组
		int[] arr = {12,23,45,55,43};
		//            0  1  2  3  4
		//2.输出删除前的数组
		System.out.println("删除元素前的数组为:"+Arrays.toString(arr));
		
		//3.删除
		/*
		arr[2] = arr[3];
		arr[3] = arr[4];
		arr[4] = arr[5];
		*/
		int index = 0;
		for(int i=index;i<=arr.length-2;i++){
			arr[i] = arr[i+1];
		}
		arr[arr.length-1] = 0;
		//4.输出删除后的数组
		System.out.println("删除元素后的数组为:"+Arrays.toString(arr));
		
	}
}

?【2】实现一个功能:删除指定元素(位置未知)

import java.util.*;
public class TestArray12{
	public static  void main(String[] args){
		//功能:给定一个数组,删除指定元素
		
		//1.给定一个数组
		int[] arr = {12,23,45,55,43};
		//            0  1  2  3  4
		//2.输出删除前的数组
		System.out.println("删除元素前的数组为:"+Arrays.toString(arr));
		
		//找到要删除的元素对应的索引
		int index = -1;
		for(int i=0;i<arr.length;i++){
			if(arr[i]==12){
				index = i;
				break;
			}
		}
		//3.删除
		/*
		arr[2] = arr[3];
		arr[3] = arr[4];
		arr[4] = arr[5];
		*/
		if(index!=-1){
			for(int i=index;i<=arr.length-2;i++){
				arr[i] = arr[i+1];
		}
		arr[arr.length-1] = 0;
		}else{//index==-1
			System.out.println("没有你要删除的元素");
		}
		//4.输出删除后的数组
		System.out.println("删除元素后的数组为:"+Arrays.toString(arr));
		
	}
}

5.详述main方法

【1】main方法:程序的入口。在同一个类中,如果有多个方法,虚拟机就会识别main方法从这个方法作为程序的入口

【2】main方法格式严格要求:

public static void main(String[] args){}

public static? ------>修饰符(暂用)

void? ----->代表方法没有返回值

main ----->见名知意名字

String[] args ----->形参? ----》不确定因素

【3】问题:程序中是否可以有其它的方法也叫main方法?

可以

public static void main(String[] args){

    }
    public static void main(String str){

        }

(方法名相同,形参列表不同,方法的重载)

【4】形参为String[],那么实参到底是什么?

public class TestArray13{
	public static  void main(String[] args){
		//从侧面验证:
		//int[] arr1;----->对数组只声明,没有后续操作,相当于 白定义了
		/*
		
		int[] arr2 = null;
		System.out.println(arr2.length);
		----->Exception in thread "main" java.lang.NullPointerException
		*/
		
		
		/*
		int[] arr3 = new int[0];
		System.out.println(arr3.length);----->输出为0
		*/
		
		/*
		System.out.println(args.length);
		这个结果证明,参数是String[],实参是  new String[0]
		默认情况下,虚拟机在调用main方法的时候就是传入了一个长度为0的数组
		*/
		
		System.out.println(args.length);
		for(String str:args){
			System.out.println(str);
		}
	}
}

手动传入实参:

有特殊符号可以加上"";没有特殊符号用空格隔开即可

6.可变参数(拓展)

public class TestArray14{
	/*
		1.可变参数:(作用)提供了一个方法,参数的个数是可变的
		int...num
		double...num
		float...num
		boolean...num
		作用:解决了部分方法的重载问题
	
		2.可变参数在JDK1.5之后加入的新特性
		3.方法的内部对可变参数的处理跟数组是一样的
		4.可变参数和其他数据一起作为形参的时候,可变参数一定要放在最后
		5.我们自己写代码,尽量不要使用可变参数
		*/
	public static  void main(String[] args){
		//method01(1);
		//method01();
		//method01(2,34,56);
		method01(23,34,45,67,87);
		//method01(new int[]{12,33,77,88,99});
	}
	public static void method01(int num2,int...num){
		System.out.println("----a");
		for(int i:num){
			System.out.print(i+"\t");
		}
		System.out.println();
		
		System.out.println(num2);
	}
}

?7.Arrays类

?(为了方便我们对数组进行操作,系统提供了一个类Arrays,我们把它当成工具类来使用)

import java.util.*;
public class TestArray15{
	public static  void main(String[] args){
		//给定一个数组
		int[] arr = {1,2,3,4,5,6};
		//toString:对数组进行遍历查看,返回的是一个字符串,看的较为清楚
		System.out.println(Arrays.toString(arr));
		
		
		//binarySearch:二分法查找,找出指定数组中的指定元素对应的索引
		//方法的使用是有前提的:一定要查看的是一个有序的数组
		//sort:排序----->升序
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr));
		System.out.println(Arrays.binarySearch(arr,4));
		
		int[] arr2 = {1,3,5,7,9};
		//copyOf:完成数组的复制
		int[] newArr = Arrays.copyOf(arr2,4);
		System.out.println(Arrays.toString(newArr));
		
		//copyOfRange:区间复制:
		int[] newArr2 = Arrays.copyOfRange(arr2,1,4);//[1-4)  --->1,2,3位置
		System.out.println(Arrays.toString(newArr2));
		
		//equals:比较两个数组的值是否一样
		int[] arr3 = {1,3,5,7,0};
		int[] arr4 = {1,3,5,7,0};
		System.out.println(Arrays.equals(arr3,arr4));//true
		System.out.println(arr3==arr4);//false  ==比较左右两侧的值是否相等,比较的是左右两侧地址的值,返回值结果一定是false
		
		
		//fill:数组的填充
		int[] arr5 = {1,3,5,7,0};
		Arrays.fill(arr5,10);
		System.out.println(Arrays.toString(arr5));
	}
}

拓展:(数组的复制)

static void? |? arraycopy(object src , int srcPos , object dest , int destPos , int length)

从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束

src ---? 源数组

srcPos? ----? 源数组中的起始位置

dest?-----? 目标数组

destPos ----? 目标数组中的起始位置

length ---- 要复制的数组元素的数量

(代码插入)

import java.util.*;
public class TestArray16{
	public static  void main(String[] args){
		//给定一个源数组
		int[] srcArr = {11,23,44,55,667,88,55,66,99};
		//给定一个目标数组
		int[] destArr = new int[10];
		
		//复制
		System.arraycopy(srcArr,1,destArr,3,3);
		//遍历查看目标数组:
		System.out.println(Arrays.toString(destArr));
	}
}

结果:

8.二维数组

【1】引入:本质上全部都是一维数组

?【2】代码:

public class TestArray17{
	public static  void main(String[] args){
		//定义一个二维数组
		int[][] arr = new int[3][];//本质上定义了一个一维数组,长度为3
		
		int[] a1 = {1,2,3};
		arr[0] = a1;
		
		arr[1] = new int[]{4,5,6,7};
		
		arr[2] = new int[]{8,9};
		
	}
}

?对应的内存分析:

【3】四种遍历方式

public class TestArray17{
	public static  void main(String[] args){
		//定义一个二维数组
		int[][] arr = new int[3][];//本质上定义了一个一维数组,长度为3
		
		int[] a1 = {1,2,3};
		arr[0] = a1;
		
		arr[1] = new int[]{4,5,6,7};
		
		arr[2] = new int[]{8,9};
		
		//读取6这个元素
		System.out.println(arr[1][2]);
		
		//对二维数组进行遍历
		/*
		//方式1:外层普通for循环+内层普通for循环
		for(int i=0;i<=2;i++){
			for(int j=0;j<arr[i].length;j++){
				System.out.print(arr[i][j]+"\t");
			}
			System.out.println();
		}
		
		
		//方式2:外层普通for循环+内层增强for循环:
		for(int i=0;i<=2;i++){
			for(int num:arr[i]){
				System.out.println(num+"\t");
			}
			System.out.println();
		}
		
		//方式3:外层增强for循环+内层增强for循环
		for(int[] a:arr){
			for(int num:a){
				System.out.println(num+"\t");
			}
		}
		*/
		//方式4:外层增强for循环+内层普通for循环
		for(int[] a:arr){
			for(int i=0;i<a.length;i++){
				System.out.println(a[i]+"\t");
			}
			System.out.println();
		}
	}
}

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 12:17:52  更:2021-12-07 12:18:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 15:00:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码