引用类型:数组的使用
数组的概念:
普通变量只能存放一个数据,如果需要一个变量,去存放多个数据, 那么就可以将变量声明为数组
数组的声明:
语法1:数据类型 变量名[]; int i[];
语法2:数据类型[] 变量名; int[] i;
声明数组之后,需要去指定数组的空间
指定空间的写法:
变量名 = new 数据类型[长度]; i=new int[10];
组合写法:
写法1:声明一个长度为5的数组arr
int[] arr = new int[5] ; 声明数组
给数组元素赋值,通过数组的索引下标赋值,每个数组都会有一个数组下标,
从0开始,到 长度-1,如果长度是5,下标就是0-4
arr[0] =1; arr[1] = 2; arr[2] = 3; ......
写法2:
int[] arr1 =new int[]{10,20,30,40,50};
写法3:
int[] arr2 = {10,20,30,40,50} ;
package com.day4.array;
/*
数组的声明和使用
*/
public class ArrayDemo01 {
public static void main(String[] args) {
//声明数组
int[] arr = new int[5];
//如果没有给下标赋值,数组中是否有值?
//数组在创建之后,如果没有给下标赋值,每个元素的默认值就是0
System.out.println(arr[0]);
System.out.println(arr[1]);
//去给下标赋值
arr[3] = 50;
System.out.println(arr[3]);
//arr[4] = "hello"; //类型必须一致
//写法2
int[] arr2 = new int[]{10,20,30};
System.out.println(arr2[1]);
//数组长度,在声明的时候就指定了
//不能获取超过长度的数组下标的值,因为不能给超过长度的下标赋值
//System.out.println(arr2[3]); //数组越界异常
// arr2[3] = 40;
// System.out.println(arr2[3]);
//写法3
int[] arr3 = {10,20,30,40,50};
System.out.println(arr3[0]);
System.out.println(arr3[1]);
System.out.println(arr3[2]);
System.out.println(arr3[3]);
System.out.println(arr3[4]);
//数组的遍历,使用循环遍历
//可以通过length属性,动态获取数组的长度
for (int i = 0; i < arr3.length ; i++) {
System.out.println(arr3[i]);
}
//快捷键 itar 回车 回车
for (int i = 0; i < arr3.length; i++) {
int i1 = arr3[i];
System.out.println(i1);
}
//增强for
for (int i :arr3) {
System.out.println(i);
}
//快捷键 iter 回车 回车
for (int i : arr3) {
System.out.println(i);
}
//写个方法,需要传入一个数组,遍历数组后
//然后将这个数组的值拼接成字符串,输出一行内容在控制台上
printArray(arr3);
printArray(arr);
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
int i2 = arr[i];
System.out.print(i2 + " ");
}
}
}
package com.day4.array;
import java.util.Scanner;
public class ArrayDemo03 {
public static void main(String[] args) {
//练习:利用数组,录入5个学生的成绩,
//录入后返回每个学生的成绩,并同时返回他们中的最高分成绩
//创建一个长度为5的数组
int[] arr=new int[5];
Scanner sc = new Scanner(System.in);
int max = 0;
//录入分数,给数组的下标赋值,通过循环完成
for (int i = 0; i < arr.length; i++) {
//给下标循环赋值(录入分数)
System.out.println("请输入第"+(i+1)+"个学生的成绩:");
arr[i] = sc.nextInt();
//录入的同时,声明一个变量,就比较每个分数,比max大,就替换max
if (arr[i]>max){
max = arr[i];
}
}
//获取分数
for (int i = 0; i < arr.length; i++) {
System.out.println("第"+(i+1)+"个学生的成绩是:"+arr[i]);
}
System.out.println("他们中的最高分是:"+max);
}
}
数组的特点:
1.数组的长度是固定的,一旦声明长度之后,不能修改
2.数组的元素是按照索引顺序。有序存放,可以通过索引下标确定元素
3.数组只能存放对应数据类型的数组
package com.day4.array;
import java.util.Scanner;
public class ArrayDemo02 {
public static void main(String[] args) {
//声明数组
int[] arr = new int[10];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
System.out.println(arr);
printArray(arr);
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
二维数组
一个数组中,嵌套了另外一个数组,或者多个数组
写法:
数据类型[] [] 数组名 = new 数组类型[m][n];
数据类型[] [] 数组名 = new 数组类型[][]{{...},{...},{...}};
数据类型[] [] 数组名 = {{...},{...},{...}};
package com.day4.array;
import java.util.Scanner;
public class ArrayDemo04 {
public static void main(String[] args) {
/*
//创建二维数组
int[][] arr = new int[3][4];
System.out.println(arr[0]);
//{{0,0,0,0},{0,0,0,0},{0,0,0,0}}
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[0][2]);
System.out.println(arr[0][3]);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.println(arr[i][j]);
}
}
*/
//现在有三个班级,每个班级有5个学生
//请分别录入3个班级中每个学生的成绩
//最后,将每个班级的班级总分输出
//1,先创建二维数组 分别为班级和学生
int[][] arr1 = new int[3][5];
//2,创建输入对象
Scanner sc = new Scanner(System.in);
//3,循环录入
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr1[i].length; j++) {
System.out.println("请输入第"+ (i+1)+"个班级的" +
"第"+ (j+1) + "个学生的成绩:");
arr1[i][j] = sc.nextInt();
}
}
//求总分
int sumMark = 0;
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr1[i].length; j++) {
sumMark += arr1[i][j];
}
System.out.println("第"+(i+1)+"个班的总分是:"+ sumMark);
//总分归0后,等待下次计算
sumMark = 0;
}
}
}
数组的排序
利用不同的算法,将数组中的数据按照顺序进行排序
常用的排序算法:冒号、选择、快速、插入、堆、希尔.....
冒号排序:
思想:
比较相邻的两个元素,如果前面的比后面的大,就做交换
第一轮排序结束后,最大值就排到了最后
重复以上操作,每一轮都找到上一轮排完之后剩下数值的最大值
最终,将数组排序完成
package com.day4.sort;
import java.util.Scanner;
public class BubbleSortDemo {
public static void main(String[] args) {
//先声明一个数组
int[] arr = {86, 57, 68, 25, 34, 2};
System.out.println("排序前:");
printArray(arr);
/*
//第一轮排序的结果{57,68,25,34,2,86}
//第一轮循环,找到最大值,放到最后
for (int i = 0; i < arr.length - 1; i++) {
//如果前的值,大于后面的值,做交换
//当i=5 arr[5] > arr[6]
if (arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("排序后:");
printArray(arr);
System.out.println("二轮排序前:");
printArray(arr);
for (int i = 0; i < arr.length - 1 - 1; i++) {
//如果前的值,大于后面的值,做交换
if (arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("二轮排序后:");
printArray(arr);
System.out.println("三轮排序前:");
printArray(arr);
for (int i = 0; i < arr.length - 1 - 2; i++) {
//如果前的值,大于后面的值,做交换
if (arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("三轮排序后:");
printArray(arr);
System.out.println("四轮排序前:");
printArray(arr);
for (int i = 0; i < arr.length - 1 - 3; i++) {
//如果前的值,大于后面的值,做交换
if (arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("四轮排序后:");
printArray(arr);
System.out.println("五轮排序前:");
printArray(arr);
for (int i = 0; i < arr.length - 1 - 4; i++) {
//如果前的值,大于后面的值,做交换
if (arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("五轮排序后:");
printArray(arr);*/
/*
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
*/
bubbleSort(arr);
System.out.println("排序后:");
printArray(arr);
}
//将冒号排序抽取到一个方法中,传入数组,将数组排序好
public static void bubbleSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
选择排序:
思想:
把数组分为无序区和有序区
数组的初始状态下,无序区是1...n,有序区是空
第一趟排序下来,从无序区中,找到最小值,和无序区的第一个值R做交换
这个时候,原来的无序区就变成了R+1...n,有序区就是刚才找到的最小值
重复循环,每次都从无序区找一个最小值,放到有序区原有数值之后
排序n-1趟之后,数组就有序了
package com.day4.sort;
public class SelectSort {
public static void main(String[] args) {
int[] arr = {86, 57, 68, 25, 34, 2};
System.out.println("排序前:");
printArray(arr);
/*
for (int i = 0; i < arr.length-1; i++) {
//声明一个最小数值的索引
//每次都拿无序区的第一个值作为最小值索引
int minIndex=i;
for (int j = i+1; j < arr.length; j++) {
//如果后面的值比开始的值小,就把最小值索引标记到小值的位置
if (arr[j]<arr[minIndex]){
minIndex=j;
}
}
//遍历完循环之后,已经标记了最小值索引
//需要跟第一个值做交换
if (i != minIndex){
int temp =arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
}
*/
selectSort(arr);
System.out.println("排序后:");
printArray(arr);
}
//插入排序方法
public static void selectSort(int[] arr){
for (int i = 0; i < arr.length-1; i++) {
//声明一个最小数值的索引
//每次都拿无序区的第一个值作为最小值索引
int minIndex=i;
for (int j = i+1; j < arr.length; j++) {
//如果后面的值比开始的值小,就把最小值索引标记到小值的位置
if (arr[j]<arr[minIndex]){
minIndex=j;
}
}
//遍历完循环之后,已经标记了最小值索引
//需要跟第一个值做交换
if (i != minIndex){
int temp =arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
}
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
快速排序:
快速排序是对冒泡排序的改进
思想:
在循环开始的时候,会指定一个中间值,一般将第一个值作为中间值
通过一次循环,会将所有数据分成独立的两部分,一般,左边部分比中间值小,右边比中间值大
以次方法,重复递归执行,分别再给左边、右边单独排序,最终将数组排序完成
具体做法:
1.选一个中间值,第一个数值
2.声明两个变量,分别做数组的第一个下标i,最后一个下标j
3.通过移动下标,依次和中间值比较,i下标值比中间值大,就等待j下标找一个比中间值小的值,然后把i和j对应的值交换
4.当i和j重的时候,也就是第一轮排序完,左边就全部是比中间小的,右边就是全部比中间大的
5.上面的一轮操作,称为一趟快速排序
6左边和右边的值,再次递归调用执行上面的快速排序即可
package com.day4.sort;
public class QuickSort {
public static void main(String[] args) {
int[] arr = {86, 57, 68, 25, 34, 2,12,4,2,56,3};
System.out.println("排序前:");
printArray(arr);
quickSort(arr,0,arr.length-1);
System.out.println("排序后:");
printArray(arr);
}
//写一个快速排序方法
public static void quickSort(int[] arr,int left,int right){
//先声明会使用的变量
int i,j,temp,t;
//指定递归结束的条件
if (left>right){
return;
}
//编写逻辑
i=left;
j=right;
temp=arr[left]; //中间值
while(i<j){
//如果j的下标值,比中间值大,j做--
while (temp<=arr[j] && i<j){
j--;
}
//如果i的下标值,比中间值小,i做++
while ((temp>=arr[i]) && i<j){
i++;
}
//如果i找到比中间值大的,j找到比中间值小的,就做交换
if (i<j){
t=arr[j];
arr[j]=arr[i];
arr[i]=t;
}
}
//把开始声明的中间值,和i/j重合的位置,做交换
arr[left]=arr[i];
arr[i]=temp;
//递归调用
quickSort(arr,left,j-1);
quickSort(arr,j+1,right);
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
插入排序:
思想:
将数组分为无序区和有序区
第一次排序,默认把第一个元素作为有序的
从无序区,第二个元素开始
从无序区,依次拿出数值,和有序区的数值挨个比较,如果比有序区最后一个数值大,
就排到有序区的最后,如果比有序区最后一个数值小,那就依次往前找,看看这个值
应该排在什么位置,找到之后,将元素插入到指定位置
package com.day4.sort;
public class InsertSort {
public static void main(String[] args) {
//先声明一个数组
int[] arr = {86, 57, 68, 25, 34, 2,12,4,2,56,3};
System.out.println("排序前:");
printArray(arr);
/*
for (int i = 1; i < arr.length; i++) {
//要插入的值
int insertNum=arr[i];
//判断已经排序元素
int j = i -1;
while (j>=0 && arr[j]>insertNum){
//将大的值,往后移动一格
arr[j+1]=arr[j];
j--;
}
//要把数值插入到指定位置
arr[j+1]=insertNum;
}
*/
insertSort(arr);
System.out.println("排序后:");
printArray(arr);
}
public static void insertSort(int[] arr){
for (int i = 1; i < arr.length; i++) {
//要插入的值
int insertNum=arr[i];
//判断已经排序元素
int j = i -1;
while (j>=0 && arr[j]>insertNum){
//将大的值,往后移动一格
arr[j+1]=arr[j];
j--;
}
//要把数值插入到指定位置
arr[j+1]=insertNum;
}
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
练习
package com.day4.sort;
public class TestSort02 {
public static void main(String[] args) {
//给一个字符串"gdeafcthmkl" 利用排序,将字符串排序好后返回
//字符串.tocharArray(); //字符串转字符数组
//String.valueof(); //字符数组转字符串
//1,声明字符串
String s = "gdeafcbthmkl";
//2,字符串转char数组
char[] chars = s.toCharArray();
//3,写一个char数组的排序方法
bubbleSort(chars);
//4,排序完后,将char数组转为字符串
String s1 = String.valueOf(chars);
System.out.println(s1);
}
public static void bubbleSort(char[] arr){
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]){
char temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
public static void printArray(char[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
排序效率
package com.day4.sort;
import java.util.Random;
public class TestSort {
public static void main(String[] args) {
//比较排序的效率
//1.往数组中存放10万条数据,数据随机生成
//随机数对象
Random random = new Random();
//调用方法,获取随机数值
int[] arr=new int[100000];
//循环存放数据
for (int j = 0; j < 100000; j++) {
arr[j]= random.nextInt(100000000);
}
//调用排序测试时间
long start=System.currentTimeMillis(); //返回当前毫秒值
//BubbleSortDemo.bubbleSort(arr); //冒泡
//QuickSort.quickSort(arr,0, arr.length-1); //快排
//SelectSort.selectSort(arr); //选择
InsertSort.insertSort(arr); //插入
long end=System.currentTimeMillis(); //返回结束的毫秒值
System.out.println(end-start);
}
}
查找
普通查找法
针对数组无序的情况下,执行全部数据遍历查找
二分查找法
针对已经排序好的数组,找中间值作比较,每次查找内容一半,可以提升查找效率
package com.day4.search;
public class SearchDemo {
public static void main(String[] args) {
/*
普通查找,从数组中,找到指定元素的下标
*/
int[] arr = {86, 57, 68, 25, 34, 2,12,4,2,56,3};
//找12在什么位置?
/* //普通查找
int index=-1;
int value=12;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == value){
index = i;
}
}
System.out.println(index);
}
*/
int[] arr1 = {11,22,33,44,55,66,77,88,99};
int index = getIndex(arr1, 77);
System.out.println(index);
}
//写一个二分查找方法
public static int getIndex(int[] arr,int value){
//先求中间索引值,通过数组的最小索引和最大索引
int max = arr.length-1;
int min = 0;
int mid = (max+min)/2;
//拿中间索引值要查找的值进行比较
while (arr[mid] != value){
if (arr[mid]>value){
max=mid-1;
}else if (arr[mid]<value){
min=mid+1;
}
//没找到的情况
if (min>max){
return -1;
}
mid=(max+min)/2;
}
return mid;
}
}
Array工具类
数组操作的工具类,jdk提供了一些方法,将来可以通过这个工具类很方便的操作数组
package com.day4.sort;
import java.util.Arrays;
/*
Array工具类测试
*/
public class TestSort03 {
public static void main(String[] args) {
int[] arr1 = {11,22,33,44,55,66,77,88,99};
int i = Arrays.binarySearch(arr1, 55);
System.out.println(i);
int[] arr2 = {10,20,30};
int[] arr3 = {10,20,30};
System.out.println(arr2 == arr3); //false
//比较数组是否相等
System.out.println(Arrays.equals(arr2,arr3)); //true
int[] arr4 = {111,22,323,344,255,166,577,188,99};
Arrays.sort(arr4); //提供的排序方法
System.out.println(Arrays.toString(arr4)); //提供的输出字符串方法
}
}