学完之后需要实现这两个问题: #生成六个1-33之间的随机数,要求不重复 特殊号码 (生成彩票) #数组扩容:先定义一个十个长度的数组,写一个方法用于向数组里面存值,每次只存入一个,反复的调用存值的这个方法,当存入的值超过十个以后,数组长度自动扩充用于存放后面的数据。
创建数组本质上还是在创建变量,适用创建变量的一系列规则。
[]-->代表的就是数组
()--> 代表的就是方法
""--> 代表的就是字符串
''--> 代表的就是字符
6.1 数组的创建
代码语言:javascript复制语法1:
数据类型 [] 数组名=new 数据类型[长度];
创建一个固定长度的数组
数组的长度固定不能发生变化
代码语言:javascript复制语法2(初始化):
数据类型[] 数组名={值1,值2...值n};
创建一个数组,并赋初始值,长度由初始元素的个数决定
代码语言:javascript复制数据类型[] 数组名=new 数据类型[]{值1,值2...值n};
注意:后面的[]中是没有长度的。
作用:
代码语言:javascript复制要存放大家的姓名,大家的成绩,大家的年龄,面对这样的需求的时候,分析出以下三点:
1、数据类型他们是统一的
2、都是有多个
3、它们表达的含意都是相同的
这时就可以使用数组来表示。
数组的定义
数组是一组具有连接性,相同类型的存储空间。数据结构(C)中被称之为线性表(顺序存储)。数组的长度固定不可变化。
6.2 数组默认值
众所周知变量需要先定义,再赋值,再使用,不然系统会报错
问题:数组是否可以只定义就使用?
答案是: 可以的,因为数组定义之初就给赋予默认值
代码语言:javascript复制import java.util.Arrays;
public class Main4 {
public static void main(String[] args) {
String[] names=new String[3];//1、先定义
System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println("========================================");
int [] ages=new int[3];
for (int i = 0; i < ages.length; i ) {
System.out.println(ages[0]);
}
System.out.println("========================================");
double[] scores=new double[3];
Arrays.stream(scores).forEach(System.out::println);
System.out.println("========================================");
char[] chs=new char[3];
for (int i = 0; i < chs.length; i ) {
System.out.println(chs[0]);
}
}
}
类型 | 值 |
---|---|
int | 0 |
double | 0.0 |
String 只要是引用数据类型默认值都是null | null |
char | 空格 |
6.3 数组的下标及使用
数组是依靠下标进行指明(找到)要操作哪一个存储空间,数组的下标从0开始,到数组的长度-1为止
例如: int []arrs=new int[5]; 问为第三个存储空间赋值为5,怎么写?
arrs[2]=5;
打印最后一个元素?
System.out.println(arrs[4]);
代码语言:javascript复制使用语法:
赋值时:
数组名[下标]=值;
使用时:
数组名[下标]
数组中有一个重要的属性length代表着当前这个数组的长度。
动态获取数据长度
语法:
数组名.length; 这是是获取长度,并不是获取最后一个元素的下标
所以
arrs.length; 获取的长度就是5;
打印最后一个元素?
System.out.println(arrs[arrs.length-1]);
代码语言:javascript复制public class Main1 {
public static void main(String[] args) {
int [] arrs=new int[5];
//为第三个元素赋值为5
arrs[2]=5;
arrs[arrs.length-1]=10;
//打印最后一个元素的值
System.out.println(arrs[4]); //不准这样去获取数组的最后一个元素。
System.out.println("数组的长度:" arrs.length);
System.out.println(arrs[arrs.length-1]);//这才是正确的获取最后一个元素的写法,任何数组都这样写
}
}
代码语言:javascript复制System.out.println(arrs[4]); //不准这样去获取数组的最后一个元素。
System.out.println(arrs[arrs.length-1]);//这才是正确的获取最后一个元素的写法,任何数组都这样写
为什么要采用arrs[arrs.length-1]来获取最后一个,是因为如果哪天你不知道数组长度的时候,就可以用它拿到最后一个
6.4 数组的赋值和打印
数组的赋值和打印一般情况下需要配合循环进行。
6.4.1初始化
代码语言:javascript复制public class Main1 {
public static void main(String[] args) {
//赋值
int [] arrs={10,20,25,31,9,8,12,33};
int [] arrs1=new int[]{4,2,13,11,9,6,63,52,78};
System.out.println(arrs.length);
System.out.println(arrs1.length);
}
}
6.4.2 循环操作
如果在定义的时候没有初始值:
只有定义没有初始化值的情况,赋值的时候要配合循环操作
代码语言:javascript复制import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
int []ages=new int[3];
Scanner input = new Scanner(System.in);
System.out.println("请输入第1名同学的成绩:");
ages[0]=input.nextInt();
System.out.println("请输入第2名同学的成绩:");
ages[1]=input.nextInt();
System.out.println("请输入第3名同学的成绩:");
ages[2]=input.nextInt();
System.out.println("第1名同学的年龄:" ages[0]);
System.out.println("第2名同学的年龄:" ages[1]);
System.out.println("第3名同学的年龄:" ages[2]);
}
}
问题这样写重复性的代码很多,这时配合循环使用
代码语言:javascript复制import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
int []ages=new int[3];
Scanner input = new Scanner(System.in);
//循环控制变量i从0开始
//循环条件到数据的最后一个为止
//变量更新 i
//操作打印提示信息并赋值
//数组的循环操作,i为控制变量,同时也是下标控制变量,一般条件i小于数组长度,i
for (int i = 0; i < ages.length; i ) {
//提示要正确,因为以前i是从1开始所以不需要做特别的处理,现在i从0开始,这里的信息要做i 1的操作,并且i 1不能改变i原本的值。
System.out.println("请输入第" (i 1) "名同学的成绩:");
ages[i]=input.nextInt();
}
for (int i = 0; i < ages.length; i ) {
System.out.println("第" (i 1) "名同学的年龄:" ages[i]);
}
}
}
注意:
数组的循环操作,i为控制变量,同时也是下标控制变量,一般条件i小于数组长度,i
提示要正确,因为以前i是从1开始所以不需要做特别的处理,现在i从0开始,这里的信息要做i 1的操作,并且i 1不能改变i原本的值。
代码语言:javascript复制import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
int []ages=new int[3];
Scanner input = new Scanner(System.in);
for (int i = 0; i <= ages.length; i ) { //i<=ages.length会造成数组下标越界
System.out.println("请输入第" (i 1) "名同学的成绩:");
ages[i]=input.nextInt();
}
for (int i = 0; i < ages.length; i ) {
System.out.println("第" (i 1) "名同学的年龄:" ages[i]);
}
}
}
如下图所示:
数组下标越界,下标控制变量超了最后一个元素的下标值,达到数组长度的时候,再用数组引用下标就会出现越界的情况。
6.4.3 增强for循环,迭代
语法:
代码语言:javascript复制for(数据类型 迭代变量名 : 数组名){}
foreach称为增强for循环,它是以一种迭代的方式对数组进行循环,迭代,用一个变量对代理数组里的每个元素,会一直从第一个元素开始一直代理到最后一个元素。
代码语言:javascript复制import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
String []names=new String[3];
Scanner input = new Scanner(System.in);
for (int i = 0; i < names.length; i ) {
System.out.println("请输入第" (i 1) "名同学的姓名:");
names[i]=input.next();
}
for(int i=0;i< names.length;i ){
String n=names[i]; //用一个变量将当前元素进行存放,以防后面的操作对当前元素使用的比数较多,书写麻烦
System.out.println(n);
}
}
}
问题,如果在一个循环中多次使用当前数组元素时可以使用一个代理变量来对元素进行使用操作。有一个更好的方式可以来替换现在的方案
for(迭代变量 : 数组名)
代码语言:javascript复制import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
String []names=new String[3];
Scanner input = new Scanner(System.in);
for (int i = 0; i < names.length; i ) {
System.out.println("请输入第" (i 1) "名同学的姓名:");
names[i]=input.next();
}
for (String n: names) {
System.out.println(n);
}
}
}
注意:
1、向迭代变量中赋值无法改变对应数组元素的值。
代码语言:javascript复制public class Main3 {
public static void main(String[] args) {
String []names=new String[3];
Scanner input = new Scanner(System.in);
for (String s : names) {
System.out.println("请输入同学的姓名:");
s=input.next();
}
for (String n: names) {
System.out.println(n);
}
}
}
结果
null
null
null
2、迭代变量的类型一定与数据的类型一致
代码语言:javascript复制public class Main4 {
public static void main(String[] args) {
int [] nums={23,12,53,123,54,76};
//jdk 1.5版本开始增强这种写法
for (int n : nums) {
System.out.println(n);
}
}
}
3、lambda表达式
代码语言:javascript复制Arrays.stream(数组名) 流式计算,链式编程
代码语言:javascript复制import java.util.Arrays;
public class Main4 {
public static void main(String[] args) {
int [] nums={23,12,53,123,54,76};
//jdk1.8版本
//System.out::println 方法的引用
//这种写法只能做打印操作
Arrays.stream(nums).forEach(System.out::println); //将所有的操作用一句代码表示
}
}
如果有问题,请设置idea
6.5 数组的应用
6.5.1 输入五个成绩求和,平均分
代码语言:javascript复制import java.util.Scanner;
public class Main4 {
public static void main(String[] args) {
//输入五个成绩,求和,求平均值,把第二个同学的成绩也打印出来,
Scanner input = new Scanner(System.in);
int sum=0;
int []scores=new int[5];
/*
这个循环只负责输入
*/
for (int i = 0; i < scores.length; i ) {
System.out.println("请输入第" (i 1) "名同学的成绩");
scores[i]=input.nextInt();
}
/*
只负责累加操作
*/
for (int i = 0; i < scores.length; i ) {
sum =scores[i];
}
System.out.println(sum);
System.out.println(sum/scores.length);
}
}
6.5.2 输入五个成绩求最高分, 最低分
代码语言:javascript复制import java.util.Scanner;
public class Main5 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int []scores=new int[5];
for (int i = 0; i < scores.length; i ) {
System.out.println("请输入第" (i 1) "名同学的成绩");
scores[i]=input.nextInt();
}
// 50 19 20 30 98
//求最高分,最低分
int max=scores[0];
int min=scores[0];
/*
for (int i = 1; i < scores.length; i ) {
if(scores[i]>max){
max=scores[i];
}
if(scores[i]<min){
min=scores[i];
}
}*/
for (int s : scores){
if(s>max){
max=s;
}
if(s<min){
min=s;
}
}
System.out.println(max);
System.out.println(min);
}
}
6.5.3 生成十个1-100之间的随机数,输入一个整数,判断输入的这个在数组中是否存在。
代码语言:javascript复制import java.util.Random;
import java.util.Scanner;
public class Main9 {
public static void main(String[] args) {
int[] nums=new int[10];
Random random=new Random();
for (int i = 0; i < nums.length; i ) {
nums[i]=random.nextInt(100) 1;
System.out.println(nums[i]);
}
Scanner input = new Scanner(System.in);
System.out.println("请输入一个1-100之间的整数:");
int search=input.nextInt();
boolean flat=false; //默认没找到 标记变量
for (int n : nums) {
if(n==search){ //输入的数与数组中的元素相等,也就是找到了
flat=true; //对flat赋值为true并跳出循环
break;
}
}
/*
如果是从break跳出来的,flat变量一定会是true,如果是循环跑了一圈跑完的这种,flat一定是false.
所以可以能过flat变量来判断有没有找到搜索的数
*/
if(flat) {
System.out.println(search "在数组中存在");
}else {
System.out.println(search "在数组中不存在");
}
}
}
代码语言:javascript复制import java.util.Random;
import java.util.Scanner;
public class Main10 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入一个1-100之间的整数:");
int search=input.nextInt();
int index = searchNum(search);
/*
* 如果返回值是-1就是没找到
* */
if(index!=-1){
System.out.println(search "在数组中存在,下标是:" index);
}else{
System.out.println(search "在数组中不存在");
}
}
/**
* 查找数组中某个数是否存在
* @param search 要查找的数
* @return 如果存在返回对应的下标值,如果不存在返回-1
*/
public static int searchNum(int search){
int[] nums=new int[10];
Random random=new Random();
for (int i = 0; i < nums.length; i ) {
nums[i]=random.nextInt(100) 1;
System.out.println(nums[i]);
}
//因为要使用下标,所以没有使用foreach循环
for (int i = 0; i < nums.length; i ) {
if(nums[i]==search){
//找到了这个数,直接return,因为return有结束方法执行的功能,所以只要return后面的代码不可能执行
return i;
}
}
//如果没有找到也就是循环正常结束,返回-1,返回-1是java对数组查找的一种常规返回的方式,因为数组的下标不可能有负数
return -1;
}
}
6.5.4 生成彩票。
代码语言:javascript复制import java.util.Random;
public class Main11 {
public static void main(String[] args) {
int []nums=new int[10];
Random random=new Random();
int n;
create:for (int i = 0; i < nums.length; i ) {
n=random.nextInt(20) 1;
for (int j=0;j<i;j ){
if(nums[j]==n){
i--;
continue create;
}
}
nums[i]=n;
}
for (int n1: nums) {
System.out.println(n1);
}
}
}
代码语言:javascript复制import java.util.Random;
public class Main12 {
public static void main(String[] args) {
int[] nums=new int[20];
Random random=new Random();
for (int i = 0; i < nums.length; i ) {
nums[i]=i 1; //确定1-20所有的数
}
int temp;
for (int i=0;i<10;i ){
int index=random.nextInt(20); //生成随机下标
//用当前的下标和随机下标中的数进行对换
temp=nums[i];
nums[i]=nums[index];
nums[index]=temp;
}
for (int i = 0; i < 10; i ) {
System.out.println(nums[i]);
}
}
}
6.6 数组做方法的参数及返回值
符号 | 含意 |
---|---|
%d | 整数占位符 |
%f | 小数占位符 %.2f 保留两位小数 |
%s | 字符串的占位符 |
%c | 字符的占位符 |
System.out.printf 打印不换行。System.out.println 打印换行。
代码语言:javascript复制public class Demo19 {
public static void main(String[] args) {
String name="张三";
int age=20;
double score=99.3;
char sex='男';
System.out.printf("姓名:%s,年龄:%d,成绩:%.2f,性别:%cn",name,age,score,sex);
System.out.printf("姓名:%s,年龄:%d,成绩:%.2f,性别:%cn","李四",23,89.1,'女');
}
}
案例:数组作为方法的参数时
代码语言:javascript复制import java.util.Scanner;
public class Main {
/*
输入5名同学的成绩和求
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] scores=new int[3]; //new 只要一new 就是重新分配堆中的内存
for (int i = 0; i < scores.length; i ) {
System.out.printf("请输入第%d名同学的成绩:n",i 1);
scores[i]=input.nextInt();
}
scoreSum(scores);
}
public static void scoreSum(int []scores){
int sum=0;
for (int s: scores) {
sum =s;
}
System.out.println(sum);
}
}
数组属于引用数据类型。
代码语言:javascript复制import java.util.Scanner;
public class Main {
/*
输入5名同学的成绩和求
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] scores1=new int[3];
int[] scores2=new int[5];
System.out.println("=====================为第一个数组赋值======================");
for (int i = 0; i < scores1.length; i ) {
System.out.printf("请输入第%d名同学的成绩:n",i 1);
scores1[i]=input.nextInt();
}
System.out.println("=====================为第二个数组赋值======================");
for (int i = 0; i < scores2.length; i ) {
System.out.printf("请输入第%d名同学的成绩:n",i 1);
scores2[i]=input.nextInt();
}
/*
根据断点查看
scores1的堆地址是644 数组长度是3
scores2的堆地址是645 数组长度是5
*/
scoreSum(scores1); //将scores1的地址传递到方法的参数中 644
scoreSum(scores2); //将scores2的地址传递到方法的参数中 645
}
//int []scores3第一次接受的是644
//int []scores3第一次接受的是645
public static void scoreSum(int []scores3){
int sum=0;
for (int s: scores3) { //第一次循环执行三次 第二次循环执行了五次
sum =s;
}
System.out.println(sum);
}
}
注意: 两个或者多个变量如果同时引用同一个空间时,其中一个变量对值进行改变,所有的变量中的值都会进行改变
代码语言:javascript复制import java.util.Scanner;
public class Main6 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] scores1={60,50,70};
changeArr(scores1);// scores1的地址传入到了方法中
for (int s: scores1) {
System.out.println(s); // 因为和scores2都是引用的同一地址,所以最后的结果是scores2改变后的结果
}
}
public static void changeArr(int []scores2){ // scores2接收就是scores1引用的地址
for (int i = 0; i < scores2.length; i ) {
scores2[i] =10;//scores2在这里对数组内容进行改变,会引发上面scores1内容的改变
}
}
}
可变参数 数据类型...变量名 ,本质是一个数组,只能用在方法的形式参数上,使用可变类型作形式参数,在调用的时候可以给实际参数那里给到任意多的参数。
代码语言:javascript复制public class Main8 {
public static void main(String[] args) {
int sum = addSum(1,2,3,45,1); //给可变参数任意多的实际参数
System.out.println(sum);
}
public static int addSum(int...nums){ //int...nums 可变参数
int sum=0;
for(int n: nums){
sum =n;
}
return sum;
}
}
它本质上是一个数组,所以也可以用数组作参数
代码语言:javascript复制public class Main8 {
public static void main(String[] args) {
int[] nums={1,2,3,45,1};
int sum = addSum(nums);//数组入参
System.out.println(sum);
}
public static int addSum(int...nums){ //int...nums 可变参数
int sum=0;
for(int n: nums){
sum =n;
}
return sum;
}
}
数组作返回值:
案例:从一个数组中求出最大值和最小值
代码语言:javascript复制public class Main7 {
public static void main(String[] args) {
/*
写一个方法出来求出最高分,高低分
*/
int[] scores1={60,50,70,75,44,99,15,43,5};
int[] result=maxAndMin(scores1); //还是得用数组来接收
System.out.println("最大值:" result[0]);
System.out.println("最小值:" result[1]);
}
public static int[] maxAndMin(int[] scores2){
int max=scores2[0];
int min=scores2[0];
for (int s: scores2) {
if(s>max){
max=s;
}
if(s<min){
min=s;
}
}
int[] result={max,min};
return result; //当一次要返回多个数据的时候可以用数组来作返回值,返回的还是引用的地址
}
}
6.7 Arrays 工具类
该类包含用于操作数组的各种方法(如排序和搜索)。
方法 | 说明 |
---|---|
static List<T> asList(T...a)[了解] | 返回由指定数组支持的固定大小的集合,方法是静态的,返回值是List,T代表的是泛型 |
static IntStream stream(int[] a)[了解] | 流式计算式 Arrays.stream(数组名).forEach(System.out::println)循环打印数组中的值。 |
static int binarySearch(int[] a,int key) | 使用二分查找法在指定的数组(排序后)中查找指定的数,返回对应的下标,找不到返回-1 |
static void sort(int[] a) | 对指定数组进行排序 |
static int[] copyof(int[] a,length) | 完全复制把指定的数组复制成一个值一样的新数组,长度小于数组,就截取指定长度的数据,长度等于原数组,就是完全一样,长度大于原数组,多出的部份采用默认值。 |
public class Main13 {
public static void main(String[] args) {
int[] nums={12,543,23,65,23,1,23,56,76,87,89,5,3,46};
Arrays.sort(nums); //对数组进行升序排列
int i = Arrays.binarySearch(nums, 1);//查找前需先排序
System.out.println(i);
}
}
int [] nums1=nums; //引用地址的赋值,两个数组引用的还是同一地址,如果现在需要,将nums中的值给nums1两个数组之间互不影响
代码语言:javascript复制import java.util.Arrays;
public class Main14 {
public static void main(String[] args) {
int[] nums={12,543,23,65,23,1,23,56,76,87,89,5,3,46};
int[] nums1=new int[nums.length];//只要看见了new就是重新创建,重新分配内存,nums多少空间nums1就是多少空间
Arrays.stream(nums).forEach(System.out::println);
System.out.println("==============================");
for (int i = 0; i < nums.length; i ) {
nums1[i]=nums[i]; //通过循环一个一个的将nums元素的值给到nums1的每一个元素上
}
nums1[0]=100;//nums1的第一个元素发生了变化
Arrays.stream(nums).forEach(System.out::println);
}
}
这是数组的完全复制,没有使用同一地址,但是数据一样,所以互不影响。
代码语言:javascript复制import java.util.Arrays;
public class Main15 {
public static void main(String[] args) {
int[] nums={12,543,23,65,23,1,23,56,76,87,89,5,3,46};
Arrays.stream(nums).forEach(System.out::println);
System.out.println("===================================================");
int[] nums1= Arrays.copyOf(nums,nums.length);
nums1[0]=100;
Arrays.stream(nums).forEach(System.out::println);
}
}
静态方法的调用:在同一个文件中,直接写方法名就行,在不同的文件中要使用 类名.方法名();
代码语言:javascript复制public class Main13 {
public static void main(String[] args) {
int i = Main10.searchNum(5); //返回值变量=类名.方法名(参数)
if(i!=-1){
System.out.println("找到了");
}else{
System.out.println("没找到");
}
}
}
如何得到程序的运行时间
代码语言:javascript复制import java.util.Arrays;
import java.util.Random;
public class Main16 {
public static void main(String[] args) {
int []nums=new int[10000000];
Random random=new Random();
for (int i = 0; i < nums.length; i ) {
nums[i]=random.nextInt(100000000);
}
//时间戳 1970.1.1 0:0:0 2022.6.14 10:10:30 1秒=1000毫秒
long start= System.currentTimeMillis(); //时间戳 当前时间到1970.1.1 0:0:0之间的毫秒数 是一个long类型数据
Arrays.sort(nums);
long end= System.currentTimeMillis();
System.out.println(end-start);
}
}
数组的扩容:
代码语言:javascript复制import java.util.Arrays;
public class Demo8 {
public static void main(String[] args) {
int []nums={5,6,9,7,8};
nums=copyOf1(nums,nums.length 1);
nums[5]=10;
System.out.println(Arrays.toString(nums));
}
//直接调用C的本地方法进行扩容
public static int[] copyOf1(int []oldArr,int newLength){
int []newNums=new int[newLength];
//原数组 从第几个元素开始进行复制,接收复制的新数组, 新数组从第几元素开始接收 接收的长度
System.arraycopy(oldArr, 0, newNums, 0 , oldArr.length);
return newNums;
}
//逻辑思路,使用java语法进行扩容
public static int[] copyOf(int [] oldArr,int newLength){
int []newNums=new int[newLength];
for (int i = 0; i < oldArr.length; i ) {
newNums[i]=oldArr[i];
}
return newNums;
}
}
System.arraycopy(oldArr, 0, newNums, 0 , oldArr.length);
第一个参数是 原数组
第二个参数是 从第几个开始复制
第三个参数是 接收的新数组
第四个参数是 从新数组的第几个元素开始接收
第五个参数是 复制多少个元素到新数组中
System.arraycopy调用是的本地方法,直接从内存中进行复制操作。
Arrays.copyOf() 就是调用的本地方法。
6.8 算法
百度: 力扣
算法可以在固定的硬件条件下
来提升系统的性能;如果没有算法,我们只能靠增加机器设备来提升系统性能。所以,算法有助于系统优化。 往往在实际开发中,为了找到⼀个最合适的算法,我们需要反复且复杂的数学分析,也叫做算法分析。
算法复杂度⼜分为时间复杂度和空间复杂度。
6.8.1 ⼤O符号
⼤O符号: 衡量时间复杂度通常使⽤”⼤O符号“。 ⼀元⼆次函数 f(x)=2x^2 2x 2;(相当2就是执行2次循环,如果x=5这个函数就是执行了62次循环) f(x)=O(x^2) 只记录最高阶的项。 对计算机而言执行1次和100次用的时间是一样的,所以阶数低的对执行时间的影响不大,只记录主要影响的参数, x^2 f(x)=2x^2 2x 2; x=10 f(x)=222 f(x)=2x^2 2x 2; x=10000 f(x)=200020002 f(x)=2x^2 2x 2; x=1000000 f(x)=2,000,002,000,002 f(x)=2x^2 2x 2; x=10000000 f(x)=200 0000 2000 0002 X越大,越接近无穷的时候 2x 2其实作用不大,所以只记录最高阶的项 O(x^2)
6.8.2 时间复杂度
是当前这个算法在程序中执行的次数
代码语言:javascript复制for (int i = 1; i <= n; i ) {
sum =i;
}
记为o(n)
代码语言:javascript复制(1 n)*n/2
程序是不是只执行1次 所以记成O(1)
代码语言:javascript复制for(int i=1;i<=100;i ){
}
程序是不是只执行100次 所以记成O(1)
代码语言:javascript复制for(int i=1;i<=10000;i ){
}
- 程序是不是只执行10000次 所以记成O(1) 如果是常数次,无论是1,还是100,还是10000都是记录成O(1),无论多少次,对于现在的计算机而言(计算机一秒可以计算几十亿次)
都是一个样,所以都记成O(1),O(1)的算法是最优秀的。
O(logn)是⼀种对数类型的时间复杂度。
对数的概念先给⼤家复习⼀下,⽐如2^x=n,转换对数就是以2为底数n的对数,记作log2 n(此处的2应该放到log下⻆,并且写⼩⼀点,但是计算机打不出来我⽤空格以示区分)。⽐如以2为底8的对数是3,记作log2 8=3.
99去这个数组中查找,如果使用循环查找,要将这个数组循环一次,算法要7次,如果采用二分查找只需要3次,O(log n) 数组长度越长,n的增长越慢。
6.8.3
代码语言:javascript复制import java.util.Arrays;
public class Main18 {
public static void main(String[] args) {
int []nums={103,75,98,42,61};
for (int i = 0; i < nums.length-1; i ) {
for(int j=0;j<nums.length-i-1;j ){
if(nums[j]>nums[j 1]){
int temp=nums[j];
nums[j]=nums[j 1];
nums[j 1]=temp;
}
}
}
Arrays.stream(nums).forEach(System.out::println);
}
}
6.8.4 选择排序
原理就是每一次去找最小值所在的位置,然后比较完成以后进行交换
代码语言:javascript复制import java.util.Arrays;
public class Main20 {
public static void main(String[] args) {
int []nums={98,75,103,42,61};
int min=0;
for (int i = 0; i < nums.length-1; i ) {
min=i; //将第一个元素作为最小的存放
for (int j = i 1; j < nums.length; j ) {
if(nums[min]>nums[j]){
min=j;
}
}
if(min!=i) {
int temp = nums[i];
nums[i] = nums[min];
nums[min] = temp;
}
}
Arrays.stream(nums).forEach(System.out::println);
}
}
6.8.5 插入排序法
代码语言:javascript复制import java.util.Arrays;
public class Main21 {
public static void main(String[] args) {
int []nums={98,75,103,42,61};
for (int i = 0; i < nums.length-1; i ) {
//i=3 42,75,98,103,61
//temp=61
int temp=nums[i 1];//插入排序每一次都是从当前i下标元素的第二个开始进行向前推
//index=4
int index=i 1;// 记录要进行插入的下标
//内层循环从后向前进行推进判断
/*
* 外层循环的第一次,内层循环最多判断一次
* 外层循环的第二次,内层循环最多判断二次
* 外层循环的第三次,内层循环最多判断三次
* 外层循环的第四次,内层循环最多判断四次
* */
//j=2
for (int j = i; j >=0 ; j--) {
if(nums[j]>temp){ //如果当前的元素值大于temp里面的用来做判断的值的时候,证明,前面的数据比现在要判断的数据大
//比它大的时候大数就向后移动一个
//42,75,75,98,103
nums[j 1]=nums[j];
//并且记录下移动这个数的位置
//index=1
index=j;
}else{
break;
}
}
//nums[1]=61
nums[index] = temp;
}
Arrays.stream(nums).forEach(System.out::println);
}
}
代码语言:javascript复制import java.util.Arrays;
public class Main22 {
public static void main(String[] args) {
int []nums={98,75,103,42,61};
for (int i = 1; i < nums.length; i ) {
int temp=nums[i];
int j;
for (j = i-1; j >=0 ; j--) {
if(nums[j]>temp){
nums[j 1]=nums[j];
}else {
break;
}
}
j ;
nums[j]=temp;
}
Arrays.stream(nums).forEach(System.out::println);
}
}
冒泡,选择,插入 基础排序算法 O(N^2)
快速,希尔,堆,归并 O(logn)
桶,基,计 O(n) --> 空间复杂度
6.8.6二分查找
代码语言:javascript复制import java.util.Arrays;
import java.util.Scanner;
public class Demo16 {
public static void main(String[] args) {
int[] nums=new int[100000000];
for (int i = 0; i < nums.length; i ) {
nums[i]=nums.length-i;
}
//二分查找法,查询之前必须排序
Arrays.sort(nums);
Scanner input = new Scanner(System.in);
System.out.println("请输入要查找的数:");
int n=input.nextInt();
int count=0;
int start=0;
int end=nums.length-1;
int middle=(start end)/2;
//死循环
while (start<=end){
if(nums[middle]>n){
end=middle-1;
}else if(nums[middle]<n){
start=middle 1;
}else {
break;
}
middle=(start end)/2;
count ;
}
if(start<=end){
System.out.println("找到了");
}else {
System.out.println("没找到");
}
System.out.println("循环执行了:" count "次");
}
}
希望本文能够帮助到刚入行java的小白,让他快速掌握java基础.