五 数组,排序
1.数组
数组存放多个同一类型的数据,是引用类型
下标从0开始
数组创建后有默认值
可以通过数组名.length得到数组的长度
/*定义数组
double[]表示double类型的数组
a表示数组名
{3,8,4.6,8.9}表示数组元素
*/
double[] a = {3,8,4.6,8.9};
1.1动态初始化
1.1.1数组的定义
①数据类型 数组名[] = new 数据类型[大小];
int a[] = new int[5];
②数据类型[] 数组名 = new 数据类型[大小];
double[] a = new double[6];
1.1.2数组的引用
数组名[下标]
a[2] 引用数组a的第3个元素
1.1.3数组的声明
①数组类型 数组名[];
int a[];
②数组类型[] 数组名;
int[] a;
1.1.4数组的创建
数组名 = new 数据类型[大小];
a = new int
1.2静态初始化
数组类型[] 数组名 = {元素值,元素值…};
int[] a = {3,6,8,56,42};
相当于
int[] a = new int[5];
a[0] = 3;
a[1] = 6;
a[2] = 8;
a[3] = 56;
a[4] = 42;
int[] arr1 = {1,2,3};
int[] arr2 = arr1; //数组赋的是地址
arr2[0] = 50; //相当于arr1[0] = 50
//共用一个地址,改变其中一个的值另一个也会改变
1.3数组拷贝
//数组1的值拷贝到数组2中
//要求数据空间是独立的
int[] arr1 = {1,2,3};
//创建一个新的数组arr2,开辟新的存储空间
//长度为arr1.length
int[] arr2 = new int[arr1.length];
for(int i = 0;i < arr1.length;i++){
arr2[i] = arr1[i];
}
arr2[0] = 90;//不会改变arr1[0]的值
1.4数组翻转
/*
数组arr1 = {58,56,78,24,39}
输出arr1 = {39,24,78,56,58}
方法1:交换
1.第一个数和最后一个数交换,
第二个和倒数第二个交换,
2.一共交换length/2次,
arr[i]和arr[length - 1 - i]交换
*/
public class 数组反转 {
public static void main(String[] args{
int[] arr1 = {58,56,78,24,39};
int temp = 0;//中间变量
for(int i = 0;i < arr1.length / 2;i++){ //交换
temp = arr1[arr1.length - 1 - i];
arr1[arr1.length - 1 - i] = arr1[i];
arr1[i] = temp;
}
for(int i = 0;i < arr1.length;i++) {
System.out.println(arr1[i]);
}
/*
方法2:逆序输出 arr3代替arr1
1.创建一个新数组arr4和arr3大小一样
2.把arr3的最后一个元素赋给arr4的第一个元素,
arr3逆序存放在arr4中
3.让arr3指向arr4的数据空间
4.遍历输出
*/
System.out.println("=====方法2=====");
int[] arr3 = {58,56,78,24,39};
int[] arr4 = new int[arr1.length];
for(int i = arr1.length-1,j = 0;i >= 0;i--,j++) {
arr4[j] = arr3[i];
}
arr3 = arr4;//arr3原来的数据空间将会被销毁
for(int i = 0;i < arr3.length;i++) {
System.out.println(arr3[i]);
}
}
}
1.5数组添加
/*
数组arr = {1,2,3},
是否要添加元素(y/n)
最后遍历输出arr
1.定义一个比arr大的数组arrNew
2.询问是否添加元素用Scanner接收
3.如果回答'y',就添加一个元素到新数组中,
直到回答'n'结束
4.让arr指向arrNew后遍历输出
*/
import java.util.Scanner;
public class 数组添加 {
public static void main(String[] args) {
Scanner myScanner = new
Scanner(System.in);
int[] arr = {1,2,3};
do{
int[] arrNew = new int[arr.length + 1];//定义一个比原数组大的新数组
System.out.println("是否添加元素:");
char answer = myScanner.next().charAt(0);
if(answer == 'n'){
break;
}
for(int i = 0;i < arr.length;i++) {
arrNew[i] = arr[i];
}
System.out.println("请输入你要添加的元素:");
int newNum = myScanner.nextInt();
arrNew[arrNew.length - 1] = newNum;
arr = arrNew;
for(int i = 0;i < arr.length;i++) {
System.out.println(arr[i]);
}
}while(true);
}
}
2.排序
将多个数据,以指定的顺序进行排列的过程
1.内部排序
将需要处理的所有数据都加载到内部存储器中进行排序(交换式,选择式,插入式)
2.外部排序
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序(合并,直接合并)
2.1冒泡排序
1.一共有n个数
2.进行了n-1轮排序,可以看成外层循环
3.每一轮可以确定一个数的位置
4.如果前>后就交换位置(从小到大)
5…每轮比较n-i-1次
2.2查找
1.顺序查找:给定一个值,按顺序查找,找到就返回其下标
2.二分查找:给定一个值,从中间开始找,是就返回下标,不是如果比中间的值小就向左查找,反之向右
import java.util.*;
import java.util.Scanner;
public class 顺序查找 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
String[] arr = {"张三","王五","赵倩"};
int index = -1;//一个索引
for(int i = 0;i < arr.length;i++){
System.out.println("请输入:");
String a = myScanner.next();
if(arr[i].equals(a)){
System.out.println(i);
index = i;
break;
}else if(index == -1){
System.out.println("查找失败!");
}
}
}
}
3.二维数组
二维数组的每个元素都是由一维数组构成
//二维数组有几个元素
int[][] arr = {{1,2,3},
{4,5,6},
{7,8,9}};
System.out.println(arr.length);//4个
二维数组的每个元素是一维数组
int[][] arr = {{1,2,3},
{4,5,6},
{7,8,9}};
for(int i = 0;i < arr.length;i++){
//遍历二维数组中有几个一维数组
for(int j = 0;j < arr[i].length;j++){
//遍历每个一维数组中的元素
System.out.println(arr[i][j]);
}
3.1二维数组声明
①int[][] arr;
②int arr[][];
③int[] arr[];
/*
输出二维数组{{1},{2,2},{3,3,3}}
*/
int[][] arr = new int[3][];
//创建二维数组,确定有几个元素
for(int i = 0;i < arr.length;i++){
arr[i] = new int[i + 1];
//给每个一维数组开辟空间
//如果没有给一维数组new,那么arr[i]就为null
for(int j = 0;j < arr[i].length;j++){
arr[i][j] = i + 1;//赋值
}
}
//遍历输出
for(int i = 0;i < arr.length;i++){
for(int j = 0;j < arr[i].length;j++){
System.out.println(arr[i][j]);
}
}
3.2杨辉三角
import java.util.*;
/*
1.输出10行
2.每行有n个数
3.每行的第一个和最后一个元素是1
4.arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1]
*/
public class 杨辉三角 {
public static void main(String[] args) {
int[][] arr = new int[10][];
for(int i = 0;i < arr.length;i++){
arr[i] = new int[i + 1];
for(int j = 0;j < arr[i].length;j++){
if(j == 0 || j == arr[i].length - 1){
arr[i][j] = 1;
}else{
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
}
for(int i = 0;i < arr.length;i++) {
for(int j = 0;j < arr[i].length;j++) {
System.out.print(arr[i][j] + " ");
}
System.out.print("\n");
}
}
}
int[] arr = new int[]{1,2,8,9};
//是可以执行的
##3.3添加一个数后数组仍有序
import java.util.*;
import java.util.Scanner;
/*
int[] arr = {12,28,68,91,103}
添加一个数后数组仍有序
思路: 定位 + 扩容
1.先确定添加数应该插入的位置,添加一个索引
2.然后扩容数组
*/
public class 添加一个数后数组仍有序 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
int[] arr = {12,28,68,91,103};
System.out.println("请输入要插入的元素");
int inserNum = myScanner.nextInt();
int index = -1;//index是要插入的位置
/*
1.定位
遍历arr数组,
如果insertNum <= arr[i],
说明i就是要插入的位置,
使index = i
如果遍历完数组后
还没发现insertnum <= arr[i],
说明index = arr.length,
即insertNum添加在最后
*/
for(int i = 0;i < arr.length;i++){
if(inserNum <= arr[i]){
index = i;
break;//找到位置后就退出
}
}
if(index == -1){
//说明遍历完数组后还没发现insertnum <= arr[i]
index = arr.length;
}
/*
2.扩容
创建一个新数组,比原数组大一个元素
把arr的元素拷贝到arrNew,
并且跳过要插入的位置
*/
int[] arrNew = new int[arr.length + 1];
for(int i = 0,j = 0;i < arrNew.length;i++) {
//i控制index的遍历,j控制原数组的遍历
if(i != index){
//没有找到要插入的位置
arrNew[i] = arr[j];
//把原数组的元素赋给新数组
j++;
}else{
arrNew[i] = inserNum;
//把添加的数放在跳过的位置
}
}
arr = arrNew;
for(int i = 0;i < arr.length;i++) {
System.out.println(arr[i]);
}
}
}