韩顺平java05(数组、排序和查找)
一维数组
三种初始化方式:
-
动态初始化(1)
数据类型 [] 数组名=new 数据类型 [大小];
int [] num =new int [10];
可以 使用数组名.length获取数组长度
Scanner sc = new Scanner(System.in); for (int i = 0; i < weight.length; i++) { weight[i] = sc.nextDouble(); } for (int i = 0; i < 5; i++) { System.out.println(weight[i]); }
-
动态初始化(2)
数据类型 [] 数组名;
int [] nums; nums = new int[5];
-
静态初始化
数据类型 [] 数组名={元素值 , 元素值 , ... };
int[] arrays = {1, 2, 3, 4, 5};
-
注意细节:
这里主要注意数组元素的类型要一致以及数组下标是否越界
小练习:
1.存贮字母表并打印
//字母表 double [] alpha = new double[26]; char a = 'A'; for (int i = 0; i < alpha.length; i++) { alpha[i] =a; a++; System.out.print((char) alpha[i] + "\t"); }
老师改进:
double [] alpha = new double[26]; for (int i = 0; i < alpha.length; i++) { alpha[i] ='A' + i; System.out.print((char) alpha[i] + "\t"); }
2.找出数组元素最大值和对应下标
double [] num = {5.6 , 56, 88 , -8 ,3.14, 4678 }; double max = 0; int maxIndex = 0; for (int i = 0; i < num.length ; i++){ if (num[i] > max){ max = num[i]; maxIndex = i; } } System.out.println("max:" + max +"index:" + maxIndex);
老师版:
double [] num = {5.6 , 56, 88 , -8 ,3.14, 4678 }; double max = num[0]; //将第一个元素假定为最大值 int maxIndex = 0; for (int i = 1; i < num.length ; i++){
//然后从第二个元素开始遍历 if (num[i] > max){ max = num[i]; maxIndex = i; } } System.out.println("max:" + max +"index:" + maxIndex);
数组赋值机制
- 基本类型数据的赋值方式为——值拷贝
int n1 = 10; int n2 = n1; n2 = 20; System.out.println("n1:" + n1); //n1:10 System.out.println("n2:" + n2); //n2:20
可以看到这里n2的变化并不会影响到n1的值
int n1 = 10; ->开辟一块空间给n1;
int n2 = n1; - > 将n1的值——10拷贝给n2; 后边的80也是一样,所以对n1没有影响。
- 而数组默认情况下是引用传递,赋的值是地址
int [] array1 = {1,2,3}; int [] array2 = array1; array1[0] = 10; for (int i = 0;i < array2.length;i++){ System.out.println(array2[i]); //10 2 3
}
这里我们先把array2的地址指向array1,然后改变了array第一个元素的值,发现array的第一个元素也随之变化了,因为数组在jvm对应的是堆,指向的是地址。所以改变array1【0】的值,array2【0】也随之变化
数组拷贝
注意:内存里分配一块空间一定会对应一个地址
因为每开辟一块新的空间都会对应一块新的地址,所以这里新的数组arr再怎么变化也不会影响到arr1了。
数组反转
1.找规律元素交换
int [] num = {1,2,3,4,5,6}; for ( int i = 0;i < num.length/2;i++){ int temp = num[i]; num[i]=num[num.length-1-i]; num[num.length-1-i]=temp; } for (int i = 0;i<num.length;i++){ System.out.println(num[i]); }
2.逆序赋值再指向新数组
int [] num = {1,2,3,4,5,6}; int [] num2 = new int[num.length]; for ( int i = num.length-1;i >= 0;i--){ num2[i]=num[num.length-1-i]; } num=num2;//将num指向num2 for (int i = 0;i<num.length;i++){ System.out.println(num[i]); }
数组扩容
- 小练习:用户输入(y/n)决定是否继续添加数据
//数组扩容 int [] num = {1,2,3,4,5,6}; System.out.print("原数组:"); for (int i = 0;i<num.length;i++){ System.out.print(num[i]+"\t"); } System.out.println(); Scanner sc = new Scanner(System.in); while (true){ System.out.println("是否继续添加数据(y/n)"); char c = sc.next().charAt(0); if (c=='n') break; int [] num2 = new int[num.length + 1]; for ( int i = 0;i <= num.length-1;i++){ num2[i]=num[i];//数组拷贝 } System.out.println("请输入新数据:"); int newarr = sc.nextInt(); num2[num.length]= newarr; //将输入的新数据添加到新数组的最后一个元素的位置 num = num2;//指向新数组 } System.out.println("添加结束"); System.out.print("新数组:"); for (int i = 0;i<num.length;i++){ System.out.print(num[i] + "\t"); }
数组缩减
//数组缩减 int [] num = {1,2,3,4,5}; System.out.print("原数组:"); for (int i = 0;i<num.length;i++){ System.out.print(num[i]+"\t"); } System.out.println(); Scanner sc = new Scanner(System.in); while (true){ System.out.println("是否继续删除数据(y/n)"); char c = sc.next().charAt(0); if (c=='n' ) //如果选择n则退出循环 { break; } int [] num2 = new int[num.length - 1]; //定义一个长度为圆原数组-1的新数组 for ( int i = 0;i <= num.length-2;i++){ // 接收0-length-2的数据 num2[i]=num[i]; } num = num2; if (num2.length == 1){ //赋值完毕后再判断新数组长度是否为1 System.out.println("无法继续缩减!"); break; } } System.out.println("删除结束"); System.out.print("新数组:"); for (int i = 0;i<num.length;i++){ System.out.print(num[i] + "\t"); }
二维数组
初始化方式
-
动态初始化(1)
数据类型 [] []数组名= new 数据类型 [大小][大小];
int [] [] num =new int [2][3];
int [][] array = new int[2][3] ; array[1][1] = 1; for (int i = 0; i<array.length;i++){//外循环次数为二维数组的行数 即array.length-1次 for (int j =0;j<array[i].length;j++){//内循环次数为一维数组的长度 即array[i].length-1次 System.out.print(array[i][j] + "\t"); } System.out.println(); } }
踩坑:一开始条件判定写成了i<array.length - 1 ,忽略了i是从0开始的
2.动态初始化(2)
3. 动态初始化(列元素个数不确定)
4.静态初始化
只有靠近数组名的那一维在定义时可以空着
内存中的存储方式:
二维数组中存储的是两个一维数组的地址,然后一维数组的地址再指向真正的数据。
- 二维数组注意细节
- 练习
排序简介
排序分类 :
- 内部排序:
内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。
有:
1.插入排序(直接插入排序);2.快速排序;
3.选择排序(简单选择排序); 4.归并排序 ;
5.冒泡排序; 6.希尔排序(对直接插入排序方法的改进)
7.堆排序; 8.基数排序;
- 外部排序:
外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。(包括合并排序法和直接合并排序法)
冒泡排序(bubble sorting)
int [] array = {56 , 63 , 54 , 2, 89}; System.out.println("排序前:"); for(int i = 0; i< array.length;i++){ System.out.print(array[i]+"\t"); } System.out.println(); for(int i = 0; i< array.length-1;i++){ //length-1是因为如果所有都比完了剩下最后一个就不用比了 for (int j =0 ; j<array.length-1-i;j++){ //这里一开始写的是j<array.length-1 看了老师的发现可以再-i 因为比较次数依次减少 if (array[j]<array[j+1]){ //如果后面的大 就和前面的交换 int temp = array[j+1]; array[j+1] =array[j]; array[j] = temp; } } } System.out.println("排序后:"); for(int i = 0; i< array.length;i++){ System.out.print(array[i]+"\t"); }
其他排序后面的数据结构再实现,这里先不继续了
查找
在java中常用的数组有两种——顺序查找和二分查找
这里我们先实现以下顺序查找的代码
查找数组中是否含有某个数,并输出下标。
int [] array = {1,2,3,4,5}; Scanner sc = new Scanner( System.in); System.out.println("请输入要查询的数字:"); int num = sc.nextInt(); int index = 0; for (int i = 0;i<array.length;i++){ if (num == array[i]){ index = i; System.out.println("找到了下标为:" + index); }else{ System.out.println("没找到"); } }
如果先这样写,就会导致不管有没有都会在不相等的时候一直走else输出“没找到”
这里我们引入一个加flag的思想,先定义一个标记,如果找到了标记改变,如果没找到判断标记没有变化的时候输出“没找到”,之前的找质数也是这个道理。
老师改进:
int [] array = {1,2,3,4,5}; Scanner sc = new Scanner( System.in); System.out.println("请输入要查询的数字:"); int num = sc.nextInt(); int index = 0; boolean flag = false; for (int i = 0;i<array.length;i++){ if (num == array[i]){ index = i; System.out.println("找到了下标为:" + index); flag = true; break; } } if (flag == false){ System.out.println("没找到"); }
这个思想666
本章练习
1.
D选项这样写是可以的但是不能在【】里加数字,让编译器判断有几个元素,E属于画蛇添足
2.
输出blue 知识点:boolean类型数组默认值为false
3.在升序数组中插入一个值使得新数组依然是升序数组
//数组插入数据,并保持 插入后数组保持升序 int [] num = {1,6,99}; System.out.print("原数组:"); for (int i = 0;i<num.length;i++){ System.out.print(num[i]+"\t"); } System.out.println(); Scanner sc = new Scanner(System.in); System.out.println("请输入新数据:"); int newNum = sc.nextInt(); int index = -1; for (int i = 0; i< num.length;i++){ if (newNum <= num[i]){ index = i; break; } } if (index ==-1)index=num.length; int [] newarr = new int[num.length+1]; for (int i = 0,j=0;i < newarr.length;i++){ if (i!= index){ // 表示可以直接拷贝元素 newarr[i]=num[j]; j++; }else{ // 这里如果走else则j就不++了,所以在newNum插入之后i比j大1 666 newarr[i]=newNum; } } num=newarr; //指向新数组,原数组销毁 System.out.print("新数组:"); for (int i = 0;i<num.length;i++){ System.out.print(num[i]+"\t"); }
5.
int [] array = new int[10]; int sum = 0; int max = 0; int index = 0; boolean flag = true; for (int i=0;i<array.length;i++){ array[i]=(int) (Math.random()*100+1); sum += array[i]; if (max < array[i]){ max = array[i]; index = i; } } System.out.println("原数组:"); for (int i=0;i<array.length;i++){ System.out.print(array[i] +"\t"); } System.out.println(); System.out.println("原数组和为:"+sum+"平均数为:"+sum/10+"最大值为:"+max + "最大值下标"+ index); System.out.println("原数组倒序:"); int [] num2 = new int[array.length]; for ( int i = array.length-1;i >= 0;i--){ num2[i]=array[array.length-1-i]; } array=num2;//将num指向num2 for (int i=0;i<array.length;i++){ if (array[i]==8)flag=false; System.out.print(array[i] +"\t"); } if (flag) System.out.println("数组不含8");
本文来自博客园,作者:紫英626,转载请注明原文链接:https://www.cnblogs.com/recorderM/p/15652774.html