数组
数组概念:
- 数组是储存同一种数据多个元素的集合。也可以看成一个容器
- 数组既可以储存基本数据类型,也可以储存引用数据类型
- 在数组中,查找元素的时间复杂度O(1)只要计算1次,即可得到元素
- 数组在堆内存中存储
- 数组的元素在内存的栈区
数组的定义格式:
- 数据类型[] 数组名;
- 数据类型 数组名[];
数组的初始化动态初始化
数组的初始化概述:
- Java中的数组必须先初始化,然后才能使用。
- 所谓初始化,就是为数组中的数组元素分配内存空间,并为每个数组元素赋值
- :在 Java 中,数组被看作是对象。数组是用 new 操作符创建的。一个数组变量实际上是一个包含数组引用的变量。
数组的初始化方式:
动态初始化:初始化时只指定数组长度,由系统为数组分配初始化
- 数据类型[] 数组名 = new 数据类型[数组长度]
- 数组长度就是数组中元素的个数
静态初始化:初始化时指定每个数组元素的数十只,由系统决定数组长度
- 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
数组创建流程:
- 函数中定义变量并起名
- 在堆内存中根据长度创建数组
- 对每一个元素进行默认初始化 int->0 ; double->0.0 ; boolean->false
- 将数组中第一个元素的地址当成整个数组的地址传递给变量
- 变量指向该数组(引用数据类型)
数组操作常见异常
- ArrayIndexOutofBoundsException 数组角标越界异常
- NullPointerException 空指针异常
数组的基本操作
-
遍历数组
int[] arr = new int[]{5,1,3,2,6,4,8,7};
for (int i = 0; i < arr.length; i++) {
//获取数组中每个角标上的元素
System.out.print(arr[i]);
}
-
数组元素查找
package com.openlab.day07;
public class Array_find {
public static void main(String[] args) {
erFen();
Traversing();
}
public static void Traversing(){
//遍历查找
int[] arr = {3,2,1,5,7,9,4};
//找元素9的角标
int key = 9;
int index = -1;
//遍历数组
for(int i=0;i<arr.length;i++){
//将相等的元素角标找出
if(arr[i]==key){
index = i;
break;
}
}
System.out.println(index);
}
public static void erFen(){
//二分查找
int[] arr ={1,2,3,4,5,6,7,8,9};
//查找元素8
int key = 8;
//创建最小角标指针
int minIndex = 0;
//创建最大角标指针
int maxIndex = arr.length-1;
//创建查找指针,指针的位置位于最大值和最小值的中间
int midIndex = (minIndex+maxIndex)/2;
//定义查找到的角标,默认没找到-1;
int index = -1;
//死循环
while(true){
//如果查找指针所处的元素大于元素8
if(arr[midIndex] > key){
//则最大角标指针位置变为查找指针的位置减1
maxIndex = midIndex-1;
//如果查找指针所处的元素小于元素8
}else if(arr[midIndex] < key){
//则最小角标指针位置变为查找指针的位置加1
minIndex = midIndex+1;
}else{
//不大,不小便是找到了,将查找指针的角标给index
index = midIndex;
//找到便结束死循环
break;
}
//执行完上面的程序,没找的情况下,重新将查找指针的位置移到现查找范围的中间
midIndex=(minIndex+maxIndex)/2;
//防止最小角标的位置越过最大角标的位置,这种情况例如:在整数1至10的范围里查找5.5
if(minIndex > maxIndex){
break;
}
}
System.out.println(index);
}
}
-
数组扩容
//创建一个新数组,将原来数组的元素添加到新数组,从而取代原来的数组 int[] arr = new int[]{1,2,3,4,5}; //- 缩 ; + 扩 int deltlSize = -2; int[] newArr = new int[arr.length+deltlSize]; for (int i = 0; i < Math.min(arr.length,newArr.length); i++){ newArr[i] = arr[i]; } arr = newArr; for (int i = 0 ; i < arr.length ; i++){ System.out.print(arr[i]+" "); }
-
数组元素排序
- 冒泡排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个。
//冒泡排序方法块,像冒泡一样选出最大值 public static void bubble_Sort(){ int[] arr = new int[]{5,1,3,2,6,4,8,7}; // i仅仅表示轮数 for (int i = 0; i < arr.length-1; i++) { // 每一次循环排序最大值便向右侧靠拢,较小的值便向左侧靠拢 for (int j = 0; j < arr.length-i-1; j++) { //此for,每次循环若j角标的元素 > j+1角标的元素则进行换位置 if(arr[j]>arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); } }
-
选择排序:假设要按升序排列一个数列。选择排序法先找到数列中最小的数,然后将它和第一个元素交换。接下来,在剩下的数中找到最小数,将它和第二个元素交换,依此类推,直到数列中仅剩一个数为止
//选择排序方法块,直接选择出最小值放在最左边 public static void choose_Sort(){ int[] arr = new int[]{5,1,3,2,6,4,8,7}; //每次循环用i角标的元素和右侧的所有元素进行比较,选出每次的最小值 for(int i =0 ; i < arr.length-1 ; i++){ for(int j = i+1; j < arr.length; j++){ //如果比i角标的元素大,则交换位置 if(arr[i]>arr[j]){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); } }
- 插入排序
//插入排序方法块
public static void insert_Sort(){
int[] arr = new int[]{5,1,3,2,6,4,8,7};
//从第二个元素开始对所在i前每一个元素进行比较
for (int i = 1; i < arr.length; i++) {
//取出当前角标i的元素
int e = arr[i];
int j = i-1;
//保证j在范围内并且比较的值大于取出的值及当前角标i的元素便将后者与前者交换
while ( j >= 0 && arr[j] > e) {
//arr[j] > e ,J角标的元素大于i取出的元素便交换位置
arr[j+1] = arr[j];
j--;
}
arr[j+1]=e;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
}
习题:
1.
/*
思路一:
数据:存储数字的数组nums 存储次数的数组counts
步骤:
1.获取一个数字
2.判断该数字
2.1 如果是0 则跳出循环
2.2 如果不是
当前数字是否在nums中
在 相应counts位置++
不在 nums扩容将数字传进去 counts扩容 1次数
3.排序nums 同时counts
*/
import java.util.Scanner;
class Class29{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int[] nums=new int[0]; //存储数字
int[] counts=new int[0];//存储次数
System.out.print("请输入数字:");
while(true){
int number=scanner.nextInt();
if(number==0){ //输入0则跳出循环
break;
}
//获取number的角标 -1 !-1
int index=indexOf(nums,number);
if(index!=-1){ //number已存在nums
counts[index]++; //相对应的次数++
}else{ //不存在 将number加入nums中 同时计数
nums=addNum(nums,number);
counts=addCount(counts);
}
}
//对结果进行排序
sort(nums,counts);
for(int i=0;i<nums.length;i++){
System.out.println(nums[i]+" occurs "+counts[i]+(counts[i]>1?" times":" time"));
}
}
//在排序nums的过程中 nums的元素要进行交换 同时对应的counts的元素进行交换
public static void sort(int[] nums,int[] counts){
for(int i=1;i<nums.length;i++){
int e=nums[i];
int f=counts[i]; //附带
int j=i-1;
while(j>0&&nums[j]>e){
nums[j+1]=nums[j];
counts[j+1]=counts[j]; //附带
j--;
}
nums[j+1]=e;
counts[j+1]=f; //附带
}
}
//向counts数组中加入新的次数默认为1
public static int[] addCount(int[] counts){
int[] arr=new int[counts.length+1];
for(int i=0;i<counts.length;i++){
arr[i]=counts[i];
}
arr[arr.length-1]=1;
return arr;
}
//向nums数组中加入元素number
public static int[] addNum(int[] nums,int number){
int[] arr=new int[nums.length+1];
for(int i=0;i<nums.length;i++){
arr[i]=nums[i];
}
arr[arr.length-1]=number;
return arr;
}
//获取number在nums数组中的角标
public static int indexOf(int[] nums,int number){
for(int i=0;i<nums.length;i++){
if(nums[i]==number){
return i;
}
}
return -1;
}
}
import java.util.Scanner;
/**
* 思路2:
* 1.将所有输入数字添加到一个数组中
* 2.对数组排序
* 3.将i角标后一样的元素进行计数
*/
public class Class29_2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = new int[0];
System.out.println("请输入数字");
while (true) {
int num = scanner.nextInt();
if (num == 0) {
break;
}
//每输入一个数对数组进行扩容
arr = addNumber(arr,num);
}
sort(arr);
//将i角标后一样的元素进行计数
for (int i = 0; i < arr.length;) {
int count = 1;
for (int j = i+1; j < arr.length; j++) {
if (arr[i] == arr[j]){
count++;
}else{
break;
}
}
System.out.println(arr[i]+" occurs "+count+(count>1?"times":"time"));
i = i+count;
}
}
/**
* 对数组扩容
* @param arr
* @param num
* @return
*/
public static int[] addNumber(int[] arr,int num){
//长度为原数组的长度+1
int[] newArr = new int[arr.length+1];
for(int i = 0; i < arr.length; i++){
newArr[i] = arr[i];
}
//num的值给新数组的最后一位
newArr[newArr.length-1] = num;
return newArr;
}
/**
* 排序方法
* @param arr
*/
public static void sort(int[] arr){
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
}
/**
* 思路3:
* 1.输入一位数将对应的角标值加1。如:输入23,角标23的位置的值加1
* 2.角标0的位置舍弃
* 3.免去了排序,值过大牺牲的空间也随着变大
*/
import java.util.Scanner;
public class Class29_3 {
public static void main(String[] args) {
int[] arr = new int[101];
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字");
while(true){
int num = scanner.nextInt();
if (num == 0) {
break;
}
//输入一位数将对应的角标值加1
arr[num]++;
}
for(int i = 1; i < arr.length;i++){
if(arr[i]>0){
System.out.println(i+" coours "+arr[i]+(arr[i]>1?"times":"time"));
}
}
}
}
2.
/**
* 思路1:
* 在输入数字的同时,进行重复的消除
* 步骤:
* 1.读入一个数字
* 2.判断该数字是否以存在于数组中
* 不存在 进去
* 存在 不管
*/
import java.util.Scanner;
public class Class30 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入10个整数");
int[] arr = new int[0];
for (int i = 0; i < 10; i++) {
int number = scanner.nextInt();
if(!isNumberInArray(arr,number)){
arr = add(arr,number);
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
/**
* 判断数组内是否存在
* @param arr
* @param number
* @return
*/
public static boolean isNumberInArray(int[] arr,int number){
for (int i = 0; i < arr.length; i++){
if(arr[i]==number){
return true;
}
}
return false;
}
/**
* 将输入的数添加到数组里
* @param arr
* @param number
* @return
*/
public static int[] add(int[] arr,int number){
int[] newArr = new int[arr.length+1];
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
newArr[newArr.length-1] = number;
return newArr;
}
}
package com.openlab.day08;
/**
* 思路2:记录添加的有效角标,每次需要添加的元素添加至该角标
* (添加元素的方法与思路一不同)
*/
import java.util.Scanner;
public class Class30_2 {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println("Enter ten number");
int[] arr = new int[10];
int size = 0;
for(int i = 0; i < 10; i++){
int number = scanner.nextInt();
if (!isNumberInArray(arr, number, size)) {
arr[size] = number;
size++;
}
}
//只用遍历有效范围内的元素
for(int i=0;i<size;i++){
System.out.print(arr[i]+" ");
}
}
public static boolean isNumberInArray(int[] arr, int number, int size) {
for (int i = 0; i < size; i++) {
if (arr[i] == number) {
return true;
}
}
return false;
}
}
package com.openlab.day08;
/**
* 思路3:在输入数字的之后,再进行重复的消除
* 1.将所有元素添加到一个数组
* 2.排序
* 3.从后往前进行比较,遇到重复的后边的内容往前移一位,记录有效范围-1
*/
import java.util.Scanner;
public class Class30_3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter ten number :");
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = scanner.nextInt();
}
sort(arr);
int size = arr.length;
for (int i = arr.length-1; i >0 ; i--) {
if (arr[i] == arr[i-1]){
for (int j = i; j < size; j++) {
arr[j-1] = arr[j];
}
size--;
}
}
for(int i=0;i<size;i++){
System.out.print(arr[i]+" ");
}
}
public static void sort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[i] > arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
}