一.数组的排序
1.1选择排序
排序的原理:
第一轮:拿数组的0索引与后面的元素一一比较如果满足条件就交换位置,时刻保证处于0索引位置的元素是最小的,顺次比较一轮后,0索引位置的元素就是最小值
第二轮:拿1索引的元素与后面的元素一一比较,满足条件就交换位置,保证1索引处的位置的元素是较小值,比较一轮之后,1索引的元素就是较小值。
每轮依次比较下去,比较轮数应该是数组的长度-1;
可以通过分析得出: 外层循环控制排序的轮数,内层循环控制着每一轮元素之间的比较
public class _05ArrayDemo {
public static void main(String[] args) {
int[] nums = {6,5,3,2,4,1};
//外层控制轮数
for (int i = 0; i < nums.length-1; i++) {
//控制着每轮的比较
for (int j = i+1; j < nums.length; j++) {
//获取要找的元素
//num[i]:就是每轮要判断是否是最小的元素的位置
//num[j]: 就是依次要比较的后续元素
if(nums[i] > nums[j]){ //条件成立,交换操作
//定义一个临时变量 保存[i]处的变量
int temp = nums[i];
//将j处的元素存在i处
nums[i] = nums[j];
//将临时变量里原[i]处的元素,放入[j]处
nums[j] = temp;
}
}
}
System.out.println(Arrays.toString(nums));
}
}
我们可以先定义一个数组{6,5,3,2,4,1}我们如果要对其进行排序,就需要设置双层for循环,外层控制比较的轮数,从0开始,到数组的长度减一,循环5次,内层循环控制着每轮中比较的次数,从1开始,循环执行5次,因为是循环嵌套循环,外层循环执行一次,内层循环执行一遍,在内层循环中,如果最左边的元素不是小的,就会与右侧的元素调换位置,我们可以引入临时变量来达成目的,最后就可以打印出结果
1.2插入排序
默认索引[0]位置的元素是有序的,从[1]开始,取出这个元素,判断一下是否需要插入,需要使用if
如果小于前面的元素则表示需要插入,那么我们就需要设置一个临时变量来储存需要插入的变量,以免被覆盖,使用第二个循环来确定需要插入的位置,如果j位置上的元素比临时变量中的元素大,那么就需要向后移动一位,移动到j+1的位置,第二层循环退出时,j上的元素应该小于或等于temp的值,那么j+1就是需要插入的位置
public class _07ArrayDemo {
public static void main(String[] args) {
int[] nums = {6,2,3,4,1,7};
int j;
//从下标1开始,拿到对应的元素,0位置上的视为已经排好序的
for (int i = 1; i < nums.length; i++) {
//拿到的这个元素判断一下是否要插入,小于前面的数表示要插入
if (nums[i] < nums[i-1]) {
int temp = nums[i];//既然要插入,该元素需要存起来,避免被覆盖
//这个for 循环的目的是要查找待插入的位置
//让选中的元素从后依次向前查找待插入的的位置
for ( j = i-1; j>=0&&temp < nums[j]; j--) {
//j位置上的元素比temp大,说明j位置上的元素要向后移动,空出位置,移到j+1的位置。
nums[j+1] = nums[j];
}
//循环退出时,j的位置上的元素应该小于或等于temp。那么j+1就是待插入的位置
nums[j+1] = temp;
}
}
System.out.println(Arrays.toString(nums));
}
}
1.3冒泡排序
原理相对来讲比较简单:从左到右,紧挨着的两个元素进行一一比较,满足条件就交换位置。
比较的轮数就是数组的长度-1,因为最后一个元素不需要比较,直接放在第一个位置就可以了
public class _08ArrayDemo {
public static void main(String[] args) {
int[] nums = {6,2,4,7,1,5};
//外层循环控制比较轮数,六个元素比较五轮,轮数等于length-1
for (int i = 0; i < nums.length-1; i++) {
//内层是控制这每轮如何比较 ,每次都要从左边开始比较,因此j从0开始
for (int j = 0; j < nums.length-1-i; j++) {
//如果前面的大于后面的,做交换操作
if (nums[j] > nums[j+1]) {
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(nums));
}
}
首先定义外层循环从0到长度-1,循环5次,内层循环从0索引开始,最大值是数组的数组的长度-1再减去i的值,因为每次排序完最后一个元素的位置就确认了,每次循环都应该固定好一个位置,
如果说前面的元素比后面的元素大,则调换他们之间的位置,把大的元素放在后面,每次外层循环一次,内层就会循环一遍,以确保最后一个位置是最大的元素。
1.4查找元素
1.4.1顺序查找
需要定义一个方法,来查找某一个元素,形参列表中输入数组名和需要查找的元素
如果在数组中能够找到元素,可以返回其索引;
public class _09ArrayDemo {
public static void main(String[] args) {
int[] nums = {100,23,48,56,78};
//需求:查找数组中是否有56,如果没有,返回-1,如果有,返回其索引
int index = searchElement(nums,88);
System.out.println(index);
int a = searchElement(nums,48);
System.out.println(a);
}
//需求:查找数组arr中是否有元素element,如果没有,返回-1,如果有,返回其索引
public static int searchElement(int[] arr,int element) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] ==element) {
index = i;
break;
}
}
return index;
}
}
首先使用静态方法定义一个数组nums,我们在main方法的下面定义一个searchElement的方法;
声明index变量并初始化值为-1,设置一个循环,循环变量初始值是0,条件是小于数组的长度,定义一个判断语句,如果输入的元素等于数组中某一个索引对应的元素,就把该索引值赋值给index,然后打破循环,如果输入的元素没有与之对应相等的,那么index返回的就是默认值-1;
因为方法的返回值类型是int 所以我们需要设置一个接受变量,然后把接受变量打印出来。
1.4.2二分法查找
定义一个方法,前提是数组必须是有序的,因为二分法的原理就是看这个元素的位置在中间值的左还是右,如果是左就在左侧继续找中间值,去和我们输入的元素比较,外层循环执行一次,内层的判断语句需要执行一遍、
public class _10ArrayDemo {
public static void main(String[] args) {
int[] nums = {1,4,6,7,9,10};
int index = binarySearch(nums, 7);
System.out.println(index);
}
/**
* 写一个使用二分查找,从int类型的数组arr中找元素element的方法,
* 找到返回其坐标,没找到返回-1
*/
public static int binarySearch(int[] arr, int element) {
int min = 0, max = arr.length - 1;
// min<=max时,表明还未找到该元素,min==max时,是最后一次查找
while (min <= max) {
//找到中间的元素下标
int mid = (min + max) / 2;
if (arr[mid] == element) {
//如果mid位置上的元素就是要找的元素,就返回下标
return mid;
}else if (arr[mid] < element) {
//如果min位置上的元素小于要找的元素,就往右侧查
min = mid + 1;//将min设置为中间下标+1,重新循环
}else {
//表明要找的元素,在中间值的左侧,往左侧查
max = mid - 1;//将min设置为中间下标-1,重新循环
}
}
//循环结束都没有遇到return,就返回-1
return -1;
}
}
首先定义了一个数组,然后再main方法下面写一个返回值是int类型的binarySearch方法,形参列表是数组名称和需要查找的元素,设置两个变量min = 0, max = 数组的长度-1,使用while循环,设置中间值是(min+max)/2,如果中间元素的值等于我们需要查找的元素,就直接返回mid的值,就是数组中元素的索引,如果中间元素的值比我们需要查找的元素小,就将min设置为mid+1,重新计算新的中间索引,继续比较,如果中间索引的元素值比我们需要查找的元素大,那么就把max设置为mid - 1,之后重新计算中间索引,直到中间索引的元素值等与我们需要查找的元素位置,如果循环结束了还没有找到我们输入的元素,就返回-1;
在我们调用方法时,需要注意声明一个接受变量,类型是int , 我们需要查找7这个元素,那么就把数组名称和7输入方法,得到返回结果;
1.5数组工具类的使用
1.5.1toString( )和binarySearch( )
Arrays.toString( );
作用是把数组类型转换为字符串类型输出,可以相当于遍历;
Arrays.binarySearch( );
作用是对数组进行二分查找,在括号里输入数组的名字和需要查找的元素,返回的结果是元素在数组中索引的值
public static void main(String[] args) {
int[] nums = {1,2,3,4,5};
String info = Arrays.toString(nums);
System.out.println(info);
int index=Arrays.binarySearch(nums, 1);
//注意:工具类里的二分查找法,必须要求升序排列
在调用方法时,由于都具有返回值,所以说需要声明一个接收变量;
1.5.2 Arrays.fill( )和Arrays.sort( )
Arrays.fill( )
作用是将指定的值填入数组中的每一个位置;第一个形参输入数组的名字,第二个形参输入想要输入的值
Arrays.sort( )
作用是对数组进行排序,只能对设置好排序规则的类进行排序,需要注意只能进行升序排序
Arrays.fill(nums,100);
System.out.println(Arrays.toString(nums));
//Arrays.sort(数组名):只能对已经提前设置好排序规则的类的数组进行排序,只能升序排序
int[] nums2 = {2,3,4,1,5};
Arrays.sort(nums2);
System.out.println(Arrays.toString(nums2));
这两个方法返回值类型是void,不需要声明接受变量,可以直接调用,输入实参即可
1.5.3 Arrays.copyOf
作用是把原数组的元素都拷贝到新数组的前面,如果原数组的长度不够,新数组的空余位置变为默认值,如果原数组和新数组的长度一样,可以理解为完全拷贝,如果原数组的长度大于新数组,可以理解为部分拷贝,需要注意:
Arrays.copyOf这个方法的返回值类型不是void,需要声明一个接收变量
//扩容:将原数组的所有元素都拷贝到新数组的最前面,然后多余的位置是默认值
int[]nums3=Arrays.copyOf(nums2,10);// [1,2,3,4,5,0,0,0,0,0]
System.out.println(Arrays.toString(nums3));
int[]nums4=Arrays.copyOf(nums2,5);//长度一样,可以理解为完全拷贝
System.out.println(Arrays.toString(nums4));
//新数组和原数组一模一样
//指定的长度小于原数组的长度,可以理解为部分拷贝,注意是从头开始拷贝(部分拷贝)
int[] nums5=Arrays.copyOf(nums2,3);
System.out.println(Arrays.toString(nums5));
}
}
第一个是把原数组拷贝到长度为10的新数组中,所以会多出来5个0;
第二个属于完全拷贝,长度都是5
第三个属于部分拷贝,新数组长度为3,所以只会接收到1,2,3三个元素;