数组的定义
之前在定义数据的时候,大部分都是用变量来存储数据。如果我们的程序中出现大量的数据怎么办?连续输入多个数字,连续输入多个坐标点,一般而言会创建多个变量存储这些数据,显得比较麻烦。这些变量基本上类型是共通的,那我们就可以用一个容器将所有的数字进行管理。类似于字符串,字符串其实就是若干个字符的容器而已,“abc”可以通过索引/角标来获取其中某一个字符。[1,2,3,4,5]类似字符串能够也可以通过索引/角标来获取其中某一个数字呢?那么这个容器我们称之为数组。
数组主要解决多变量多数据的存储问题,方便程序后期统一维护操作数据。
数组的本质就是一系列空间大小相等且地址连续的一片存储空间。
为什么空间大小是相等的呢?就是为了方便统一维护我们的数据,必须得保证数据之间的类型是一样的。(多个同类型的变量空间连在一起组成的结构叫数组)。
为什么变量空间的地址是连续的呢?就是为了方便统一操作我们的数据。见下图

1.数组就是一片地址连续且空间大小一致的存储空间(但是每个空间存的还是其他数据的地址)
2.数组存在于堆内存中,但凡在堆中存储的数据都称之为 对象
但凡在堆内存中创建的对象都会有默认初始值:整数类型默认0;浮点类型默认0.0;布尔类型默认false;引用数据类型(对象)默认null。
3.数组提供角标来访问数组当中的元素
4.数组变量存的就是数组在堆内存中首元素的地址
5.数组通过角标来访问元素的具体计算方式是 所要访问数据的地址=首元素地址+角标*数据类型大小
6.数组一旦定义下来,其长度不可改变;数组中有几个地址?就看数组有几个元素空间<==>数组的长度
7.创建数组时必须明确规定大小或内容
数据类型[] 数组名=new 数据类型[长度]:创建数组只指定长度但不指定内容
数据类型[] 数组名=new 数据类型[]{1,2,3,4,5}:创建数组指定内容(指定长度)
数据类型[] 数组名={1,2,3,4,5}:创建数组指定内容(指定长度)
[]表示是一维数组;[][]表示二维数组。
数组的内存分析:
数组常见错误:ArrayIndexOutOfBoundsException 数组角标越界;NullPointerException 空指针异常
基本数组操作:
遍历;赋值;最大值/最小值
查找操作:
线性查找;二分查找;*斐波那契查找
排序操作:
选择排序;冒泡排序;插入排序;*归并排序;*堆排序;*快速排序;计数排序;*基数排序;*桶排序。
//四种排序方法
class Test02{
public static void main(String[] args){
//1.选择排序O(n^2)
selectSort();
//2.冒泡排序O(n^2)
bubbleSort();
//3.插入排序O(n^2)
insertSort();
//4.计数排序O(n+m)
/*
上述三个排序都是根据数据之间的大小关系进行比较排序的
计数 基数 桶 都是根据数据本身的特性比较 与大小无关的排序
这些排序只针对整数
是一个典型的牺牲空间换时间的排序
*/
countSort();
}
public static void countSort(){
int[] arr={8,5,9,2,7,4,6,1,3,10,-3,-2,-10};
int min=arr[0];
int max=arr[0];
for(int i=0;i<arr.length;i++){//O(n)
if(arr[i]>max){
max=arr[i];
}
if(arr[i]<min){
min=arr[i];
}
}
int[] nums=new int[max-min+1];
int offset=min;
for(int i=0;i<arr.length;i++){//O(n)
nums[arr[i]-offset]++;
}
int index=0;
for(int i=0;i<nums.length;i++){//O(m)
if(nums[i]!=0){
for(int j=0;j<nums[i];j++){
arr[index++]=i+offset;
}
}
}
show(arr);
}
public static void insertSort(){
int[] arr={8,5,9,2,7,4,6,1,3};
int e;
int j;
for(int i=1;i<arr.length;i++){
e=arr[i];
for(j=i;j>0&&arr[j-1]>e;j--){
arr[j]=arr[j-1];
}
arr[j]=e;
}
/*
for(int i=1;i<arr.length;i++){
for(int j=i;j>0&&arr[j-1]>arr[j];j--){
swap(arr,j,j-1);
}
}
*/
show(arr);
}
public static void bubbleSort(){
int[] arr={8,5,9,2,7,4,6,1,3};
for(int i=0;i<arr.length-1;i++){//-1是少一轮比较
for(int j=0;j<arr.length-1-i;j++){//-1避免重复比较和角标越界
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
}
}
}
show(arr);
}
public static void selectSort(){
int[] arr={8,5,9,2,7,4,6,1,3};
for(int i=0;i<arr.length-1;i++){//-1是因为没有必要进行最后一个数字的比较
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
swap(arr,i,j);//即用-即释放
}
}
}
show(arr);
}
public static void swap(int[] arr,int i,int j){
//1.借助三方变量进行交换
//适用于所有的数据类型 比较通用
/*
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
*/
//2.借助加减法运算进行交换
//只适用于数字相关的数据类型
arr[i]=arr[i]+arr[j];
arr[j]=arr[i]-arr[j];
arr[i]=arr[i]-arr[j];
//3.借助位运算进行交换
//只适用于整数相关的数据类型
}
public static void show(int[] arr){
//[1,2,3,4,5,6,7,8,9]
String s="[";
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
s+=arr[i]+"]";
}else{
s+=arr[i]+",";
}
}
System.out.println(s);
}
}
数组的扩容
class Test01{
/*
数组的扩容,就是创建一个新的数组 将元素赋值进去之后,将新数组的地址返回即可
*/
public static void main(String[] args){
int[] arr=new int[]{1,2,3};
arr=copyOf(arr,arr.length+1);
arr[arr.length-1]=10;
System.out.println(arr[3]);
}
public static int[] copyOf(int[] arr,int newLen){
int[] newArr=new int[newLen];
for(int i=0;i<arr.length;i++){
newArr[i]=arr[i];
}
return newArr;
}
}
public static void binarySearch(){
//二分查找有个前提 数组必须有序
/*
最好情况 查46 1次就出来了
最坏情况 查12/60 O(logn)
*/
int[] arr={12,17,21,32,38,41,46,49,50,50,51,59,60};
int key=46;
int index=-1;
int min_index=0;
int max_index=arr.length-1;
int mid_index=(min_index+max_index)/2;
while(arr[mid_index]!=key){
if(key<arr[mid_index]){
max_index=mid_index-1;
}
if(arr[mid_index]<key){
min_index=mid_index+1;
}
if(min_index>max_index){
index=-1;
break;
}
mid_index=(min_index+max_index)/2;
}
System.out.println(mid_index);
}
public static void linearSearch(){
/*
最好情况 查10 1次就出来了
最坏情况 查5 10次才出来
当数组的长度越大的话 最坏情况越差
时间复杂度(最坏情况) O(n) 线性阶
*/
int[] arr={10,2,8,3,1,6,4,7,9,5};
int key=11;
int index=-1; //key元素不存在
for(int i=0;i<arr.length;i++){
if(arr[i]==key){
index=i;
break;
}
}
System.out.println(index);
}
}
import java.util.*;
class test5_1{
public static void main(String[] args) {
int[] num = createArrays();
Arrays.sort(num);
for (int i = 0; i < num.length; i++) {
if (i == 0 || (num[i] != num[i - 1])) {
System.out.println(num[i] + "在数组中出现了" + getCount(num[i], num) + "次");
}
}
}
public static int[] createArrays() {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入1~100之间的整数(以0作为结束):");
int[] num = new int[100];
int i = 0;
int input;
while (i >= 0) {
input = scanner.nextInt();
if (input != 0) {
num[i] = input;
i++;
} else {
break;
}
}
int zeroIndex = getZeroIndex(num);
int[] newNum = new int[zeroIndex];
System.arraycopy(num, 0, newNum, 0, zeroIndex);
return newNum;
}
public static int getZeroIndex(int[] num) {
for (int i = 0; i < num.length; i++) {
if (num[i] == 0) {
return i;
}
}
return -1;
}
public static int getCount(int indexNum, int[] num) {
int count = 0;
for (int i = 0; i < num.length; i++) {
if (indexNum == num[i]) {
count++;
}
}
return count;
}
}
import java.util.*;
class test5_2{
public static void main(String[] args) {
System.out.print("请输入10个正整数:");
int[] inputNumList = inputNumList();
System.out.println("当前的数组为:" + Arrays.toString(inputNumList));
resultNumList(inputNumList);
}
public static int[] inputNumList() {
Scanner scanner = new Scanner(System.in);
int[] inputNumList = new int[10];
for (int i = 0; i < 10; i++) {
inputNumList[i] = scanner.nextInt();
}
return inputNumList;
}
public static void resultNumList(int[] inputNumList) {
int counts = 0;
ArrayList<Integer> resultNumList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
for (int j = i; j < 10; j++) {
if (inputNumList[i] == inputNumList[j] && i != j) {
inputNumList[j] = -1;
}
}
if (inputNumList[i] != -1) {
counts++;
resultNumList.add(inputNumList[i]);
}
}
System.out.println("其中不同的数字个数为:" + counts);
System.out.print("最后的结果为:" + Arrays.toString(resultNumList.toArray()));
}
}
import java.util.*;
class test5_3{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num;
System.out.print("请输入数字(第一个数表示数组长度):");
num = scanner.nextInt();
int[] numArray = new int[num];
for (int i = 0; i < num; i++) {
numArray[i] = scanner.nextInt();
}
System.out.println("输入的数组为:" + Arrays.toString(numArray));
if (isSorted(numArray)) {
System.out.print("该数组已经按升序排列");
} else {
System.out.print("该数组没有按升序排列");
}
}
public static boolean isSorted(int[] numArray) {
int[] tmpArray = new int[numArray.length];
System.arraycopy(numArray, 0, tmpArray, 0, numArray.length);
Arrays.sort(tmpArray);
return Arrays.equals(tmpArray, numArray);
}
}
import java.util.*;
class test5_5{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入数组1(第一个数字表示数组长度):");
int[] list1 = new int[scanner.nextInt()];
for (int i = 0; i < list1.length; i++) {
list1[i] = scanner.nextInt();
}
System.out.print("请输入数组2(第一个数字表示数组长度):");
int[] list2 = new int[scanner.nextInt()];
for (int i = 0; i < list2.length; i++) {
list2[i] = scanner.nextInt();
}
if (equals(list1, list2)) {
System.out.print("这两个数组完全相同");
} else {
System.out.print("这两个数组不完全相同");
}
}
public static boolean equals(int[] list1, int[] list2) {
return Arrays.equals(list1, list2);
}
}
class test5_6{
public static void main(String[] args){
int[] arr={1,1,1,1,2,2,2,2,2,3,3,3,3,3,4};
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;
}
}
if(count>=4){
System.out.println(arr[i]);
return;
}
i+=count;
}
System.out.println("没有!");
}
}
import java.util.*;
class test5_7{
public static void main(String[] args){
int[] list1={1,3,5,7,9};
int[] list2={2,4,6,8,10};
System.out.println(Arrays.toString(merge(list1,list2)));
}
public static int[] merge(int[] list1,int[] list2){
if(list1==null&&list2==null){
return null;
}
if(list1==null){
return list2;
}
if(list2==null){
return list1;
}
//只有两个都不是null的情况再考虑具体操作
int[] list3=new int[list1.length+list2.length];
int p1=0;
int p2=0;
int p3=0;
while(true){
if(p1==list1.length&&p2==list2.length){
break;
}
if(p1<list1.length&&p2==list2.length){
list3[p3++]=list1[p1++];
}else if(p1==list1.length&&p2<list2.length){
list3[p3++]=list2[p2++];
}else{
if(list1[p1]<=list2[p2]){
list3[p3++]=list1[p1++];
}else{
list3[p3++]=list2[p2++];
}
}
}
return list3;
}
}
本文详细介绍了Java中的数组,包括数组的定义、内存分析、基本操作如遍历和赋值,以及查找和排序算法。强调了数组作为连续存储空间的重要性,并提到了常见的数组操作错误及解决方案,如数组角标越界和空指针异常。此外,还概述了各种排序算法的应用,如选择排序、冒泡排序和高级排序算法如归并排序和快速排序。
1169

被折叠的 条评论
为什么被折叠?



