同一种类型数据的集合,其实数组就是一个容器。
数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
定义格式:
格式1: 元素类型[] 数组名=new 元素类型[元素个数或数组长度];
eg:int[] arr=new int[3] ; (数组中元素默认为0)
格式2: 元素类型[] 数组名=new 元素类型[]{元素,元素,元素,......};
元素类型[] 数组名={元素,元素,元素,......};
eg:int[] arr=new int[]{3,5,1,7};
int[] arr={3,5,1,7}; (这两个通常是通用的)
如果要输出一个数组的所有数: (可以利用数组名.length获取数组的长度)
for(int x=0;x<arr.length;x++)
System.out.println("arr["+x+"]="+arr[x]);
for语句要是换成for(int x=0;x<arr.length;x+=2),就是输出偶数位。
for语句要是换成for(int x=arr.length-1;x>=0;x--),就是逆序输出所有数。
核心思想就是操作角标。
1.获取最值
2.排序
选择排序:for(int x=0;x<arr.length-1;x++)
{ for(int y=x+1;y<arr.length;y++)
{
if(arr[x]>arr[y])
{
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
}
}
冒泡排序:for(int x=0;x<arr.length-1;x++)
{
for(int y=0;y<arr.length-1-x;y++) //这里y的范围减一是为了避免角标越界,
{
if(arr[y]>arr[y+1]) //又减x是为了让外循环增加一次,内循环参数与比较的元素的个数递减。
{
int temp=arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
3.查找
public static int getIndex(int[] arr,int key)
{
for(int x=0;x<arr.length;x++)
{
if(arr[x]==key)
return x;
}
return -1; //没找到key这个数就返回-1,角标没有负的,就代表没找到这个数。
}
二分查找(折半查找) //前提是数组的数要从小(大)到大(小)排列
public static int halfSearch(int[] arr,int key)
{
int min,mid,max;
min=0;
max=arr.length-1;
mid=(min+max)/2;
while(arr[mid]!=key)
{
if(key>arr[mid])
min=mid+1;
else if(key<arr[mid])
max=mid-1;
if(max<min)
return -1; //没找到这个数
mid=(min+max)/2;
}
return mid;
}
注意:无序的数组不要想着先给他排序,再折半查找,排序之后角标就变了,
所以找的角标也是错的,所以不用二分查找,直接用上面那个基本的方法。
二维数组:定义格式1:int[][] arr=new int[3][2]
定义格式2:int[][] arr=new int[3][]
定义格式3:int[][] arr={{1,2,3},{4,5,6},{7,8,9}};
arr.length可以理解为行数 arr[0].length可以理解为列数
数组应用的实例:
1.获取最值
package day05;
public class GetMax
{
public static void main(String[] args)
{
int[] arr=new int[]{-12,98,134,-63,-10};
int Max=getmax_2(arr);
System.out.println("Max="+Max);
}
public static int getmax(int[] arr) //直接对数组中的数操作
{
int max=arr[0];
for(int i=1;i<arr.length;i++)
{
if(arr[i]>max)
max=arr[i];
}
return max;
}
public static int getmax_2(int[] arr) //对数组中数的角标操作
{
int max=0;
for(int i=1;i<arr.length;i++)
{
if(arr[i]>arr[max])
max=i;
}
return arr[max];
}
}
2.数组中的查找功能
package day05;
public class Search
{
public static void main(String[] args)
{
int[] arr=new int[]{14,16,19,29,34,68,79};
int index=halfSearch(arr,34); //用halfSearch,数组arr必须有顺序的排列(从小到大或从大到小)
System.out.println(index); //输出所查找的数的角标;
}
public static int getIndex(int[] arr,int key)
{
for(int x=0;x<arr.length;x++)
{
if(arr[x]==key)
return x;
}
return -1; //没找到key这个数就返回-1,角标没有负的,就代表没找到这个数。
}
public static int halfSearch(int[] arr,int key)
{
int min,mid,max;
min=0;
max=arr.length-1;
mid=(min+max)/2;
while(arr[mid]!=key)
{
if(key>arr[mid])
min=mid+1;
else if(key<arr[mid])
max=mid-1; //没找到这个数
if(max<min)
return -1;
mid=(min+max)/2; //这句别忘了,没这句就是死循环。
}
return mid;
}
}
3.关于查找的一个练习
package day05;
/*给定一个有序的数组,如果往该数组中存储一个元素,并保证该数组还是
有序的,那么这个元素的角标应如何获取?
*/
public class SearchPractice
{
public static void main(String[] args)
{
int[] arr=new int[]{1,26,36,49,64,82,103};
int num=50;
int index=halfSearch(arr,num);
System.out.println(index);
}
public static int halfSearch(int[] arr,int key)
{
int min,mid,max;
min=0;
max=arr.length-1;
mid=(min+max)/2;
while(arr[mid]!=key)
{
if(key<arr[mid])
max=mid-1;
else if(key>arr[mid])
min=mid+1;
if(max<min)
return min; //返回的是num的插入位置。
mid=(min+max)/2;
}
return mid;
}
}
/*其实这道题很简单,只是把二分查找max<min时return -1换成了return min。
要加的元素肯定是数组里没有的,所以最后一定会max<min,此时min和max
角标是相邻的,max是较小的那个,而要加的数大小正好在这两个数之间,所以,
只需返回min的值,即可获取要加的元素的角标。
*/
4.数组中的排序问题
package day05;
public class Sort
{
public static void main(String[] args)
{
int[] arr=new int[]{19,3,6,14,23,0};
PrintArray(arr); //打印排序前的数组;
SelectSort_2(arr); //任意选择一种排序方式;
PrintArray(arr); //打印排序后的数组;
}
public static void PrintArray(int[] arr) //打印数组的函数
{
System.out.print("[");
for(int x=0;x<arr.length;x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
public static void SelectSort(int[] arr) //选择排序的函数;
{
for(int x=0;x<arr.length-1;x++)
{
for(int y=x+1;y<arr.length;y++)
{
if(arr[x]>arr[y])
Swap(arr,x,y);
}
}
}
public static void SelectSort_2(int[] arr) //另一种比较高效的选择排序;
{
for(int x=0;x<arr.length-1;x++)
{
int num=arr[x];
int index=x;
for(int y=x+1;y<arr.length;y++) //用num记录较小数,index记录较小数的角标,一次大循环之后就找出最小值,然后只需换位一次,以此类推。
{
if(arr[x]>arr[y])
{
num=arr[y];
index=y;
}
}
if(index!=x) //index=x就说明第一个就是最小值,就不需要换位。
Swap(arr,x,num);
}
}
public static void BubbleSort(int[] arr) //冒泡排序的函数
{
for(int x=0;x<arr.length-1;x++)
{
for(int y=0;y<arr.length-1-x;y++) //减一避免越界,减x让内循环参与比较的元素个数递减。
{
if(arr[y+1]<arr[y])
Swap(arr,y,y+1);
}
}
}
public static void Swap(int[] arr,int a,int b) //数组中两个数换位的函数
{
int temp=0;
temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
}
5.获取一个整数的16进制表现形式
package day05;
/*
获取一个整数的16进制表现形式
如果数据出现了对应关系,而且对应关系的一方是有序的数字编号,并作为角标
使用,这是就要想到数组的使用,将这些数据存储到数组中,根据运算的结果作为
角标直接去查数组中对应的元素即可。
这就是查表法,是数组常见的一种应用。
对应关系:
1,2,3,4,5,6,7,8,9,A ,B ,C ,D ,E ,F ,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
*/
public class toHex
{
public static void main(String[] args)
{
int m=60;
toHex_2(m);
}
public static void toHex_1(int num) //这个方法输出的有好多没用的0,而且是反的,不够完美。
{
for(int x=0;x<8;x++) //每一个二进制码有8个字节,每一个字节对应一个16进制字符
{
int temp=num&15; //相当于取出了num的二进制的最后一个字节,详见day03运算符
if(temp>9)
System.out.print((char)(temp-10+'A')); //用ASCII码值算的,输出时又做了一次强制类型转换
else
System.out.print(temp);
num=num>>>4; //位运算,无符号右移4位
}
}
public static void toHex_2(int num)
{
if(num==0) //如果没有这句,则输入0时,程序没有结果
{
System.out.println("0");
}
//定义一个对应关系表。
char[] chs={'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F',};
/*查表会查到比较多的数据,数据一多,就先存储起来,再进行操作。
所以再定义一个数组,相当于临时容器。
*/
char[] arr=new char[8];
int pos=arr.length; //for循环固定转8次,有许多是多余的,自定义一个脚标,就不用写for了
while(num!=0)
{
int temp=num&15;
arr[--pos]=chs[temp]; //直接从arr的最后一位往前存,这样带回输出的就不会反了。
num=num>>>4;
}
for(int x=pos;x<arr.length;x++) //直接从pos开始输出,把前面多余的0就去掉了
System.out.print(arr[x]);
}
}
6.一个关于进制转换的函数
package day05;
//进制转换的函数
public class trans
{
public static void main(String[] args)
{
int m=60;
toBinary(m); //转到二进制
toOctal(m); //转到八进制
toHex(m); //转到十六进制
}
//十进制 --> 二进制
public static void toBinary(int num)
{
trans_1(num,1,1); //和1做与运算,右移1位
}
//十进制 --> 八进制
public static void toOctal(int num)
{
trans_1(num,7,3); //和7做与运算,右移3位
}
//十进制 --> 十六进制
public static void toHex(int num)
{
trans_1(num,15,4); //和15做与运算,右移4位
}
public static void trans_1(int num,int base,int offset)
{
if(num==0) //如果没有这句,则输入0时,程序没有结果
{
System.out.println("0");
}
//定义一个对应关系表。
char[] chs={'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F',};
/*查表会查到比较多的数据,数据一多,就先存储起来,再进行操作。
所以再定义一个数组,相当于临时容器。
*/
char[] arr=new char[8];
int pos=arr.length; //for循环固定转8次,有许多是多余的,自定义一个脚标,就不用写for了
while(num!=0)
{
int temp=num&base;
arr[--pos]=chs[temp]; //直接从arr的最后一位往前存,这样带回输出的就不会反了。
num=num>>>offset;
}
for(int x=pos;x<arr.length;x++) //直接从pos开始输出,把前面多余的0就去掉了
System.out.print(arr[x]);
System.out.println();
}
}