一,数组翻转
1.概述:数组对称索引位置上的元素互换,最大值数组序号是数组长度减一
创建跳板temp,进行min和max的互换,然后min自增,max自减,当min>=max的时候停止互换,代表到中间值
用代码实现
public class Demo01Reverse {
public static void main(String[] args) {
//定义一个静态数组
int arr [] ={1,2,3,4,5,6,7};
for(int min=0,max = arr.length-1;min<max;min++,max--){
//进行换位
int temp = arr[min];
arr[min]= arr[max];
arr[max]= temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
二,冒泡排序
数组的排序,是将数组中的元素按照大小进行排序,默认都是以升序的形式进行排序,数组排序的方法很多,我们讲解的是数组的冒泡排序。
排序,都要进行数组 元素大小的比较,再进行位置的交换。冒泡排序法是采用数组中相邻元素进行比较换位。
arr[i](前一个元素) arr[i+1](后一个元素)
比如以下数组
5 4 3 2 1
进行0,1号位的数字比较
4 5 3 2 1
然后又进行1,2号位的数字比较
4 3 5 2 1
然后2,3号位比较
4 3 2 5 1
最后3,4号位比较
4 3 2 1 5
实现位置的交换依然和前面数组翻转一样,创建一个跳板temp进行交换
代码实现
首先,定义数组
public class Demo02Bubble {
public static void main(String[] args) {
int[] arr = {5,4,3,2,1};
进行第一轮冒泡
/* 第一圈 */
for (int i = 0; i < arr.length; i++) {
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr [i+1];
arr[i+1] = temp;
}
}
测试,出现警告
这是为什么呢
其实是循环的时候突破了数组的最大序号
因为arr.length就等于5,所以i能取到的最大值是4,所以i+1=5,突破了最大限制
改为arr.length-1
成功,然后进行第二圈
//第二圈
for (int i = 0; i < arr.length-1; i++) {
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr [i+1];
arr[i+1] = temp;
}
}
第二圈代码和第一圈一样,也没问题,但也和第一圈一样比较了4次,但我们可以不必做这个重复功,因为第一次比较完了一个数,所以我们可以减去一次循环来表示可以少比较的次数,所以可以写成arr.length-1-1,最后面减的这个数可以看成是前面冒泡过的数的个数(圈数)
//第二圈
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;
}
}
现在进行第三圈第四圈,同样我们减去前面冒泡过的数的个数
//第三圈
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;
}
}
//第四圈
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;
}
}
运行结果
但我们可以再进行优化,这几圈的变化非常细微,只有一个数一个位置在变
如果最后面减的数是前面的圈数的话,那也就等于i啊,我们可以再在外面套一层循环,利用自加i来代替这几圈唯一变的减数
/*
外层循环代表比较了几圈
n-1圈
*/
for (int j = 0; j < arr.length-1; j++) {
for (int i = 0; i < arr.length-1-j; i++) {
/*
内层循环代表每一圈比较的次数
每圈都少比较一次
*/
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr [i+1];
arr[i+1] = temp;
}
}
}
由此而来,化繁为简,减小了时间,空间复杂度
完整代码如下
public class Demo02Bubble {
public static void main(String[] args) {
int[] arr = {5,4,3,2,1};
/*
第一圈
越界原因:当i变化到4的时候-> arr[4]>arr[5] -> 直接操作了5索引,所以越界了
越界解决:我们可以让arr.length-1
如果arr.length-1-> 比较就是i<4 -> 此时i最大可以变化到3
当i变化到3时 -> arr[3]>arr[4] -> 正好是最后两个元素进行比较
*/
for (int i = 0; i < arr.length-1-0; i++) {
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr [i+1];
arr[i+1] = temp;
}
}
//第二圈
/*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;
}
}*/
//第三圈
/*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;
}
}*/
//第四圈
/*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;
}
}*/
/*
外层循环代表比较了几圈
n-1圈
*/
for (int j = 0; j < arr.length-1; j++) {
for (int i = 0; i < arr.length-1-j; i++) {
/*
内层循环代表每一圈比较的次数
每圈都少比较一次
*/
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr [i+1];
arr[i+1] = temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
三,二分查找(一尺之锤,日取其半,万世不竭)
1.前提:数组中的数据必须是有序的
2.查询思想:
a.老式查询:遍历数组,一个一个比较 -> 查询效率慢
b.二分查找:每次找中间索引对应的元素进行比较查询(每一次查询少一半数据)
首先,因为min和max会因为查找数所在数组的位置不同而改变所以不能定义min就是arr[0]或max就是arr[8],min默认为0,max为arr.length-1,mid就是二者取中。
key为查询数,是指想查的数组中的数,查询出的是数组序数代表 含的数。
前提:当min<=max时
当查询数大于或小于数组序数上所代表的数时,通过移动min和max直接排掉一半的数,来不断的锁定范围,直到找到查询数所在的位置(这个方法很像一尺之锤,日取其半,万世不竭,不过是有目标的取),当查询数等于数组序数上所代表的数时,停止查找,返回序数表示找到了。
当然还有特殊情况,就是查询数不存在在数组中,那么当min>max时,就不找了,返回-1表示找不到。
代码实现
public static int binary(int[] arr,int data){
//定义三个变量,分别代表最大索引,最小索引,中间索引
int min = 0;
int max = arr.length-1;
int mid = 0;
//查找
while (min<=max){
mid = (min+max)/2;
if(data>arr[mid]){
min = mid+1;
}else if(data<arr[mid]){
max = mid-1;
}else{
return mid;
}
}
return -1;
}
我们发现代码实现和理论方法步骤不同,没有在一开始表示mid = (min+max)/2,因为要循环的算中间索引,在一进入循环时,在while(外层循环)内,再进行计算。
在main函数内调用方法进行输出,完整代码如下
public class Demo03Binary {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9};
int index = binary(arr, 7);
System.out.println(index);
}
public static int binary(int[] arr,int data){
//定义三个变量,分别代表最大索引,最小索引,中间索引
int min = 0;
int max = arr.length-1;
int mid = 0;
//查找
while (min<=max){
mid = (min+max)/2;
if(data>arr[mid]){
min = mid+1;
}else if(data<arr[mid]){
max = mid-1;
}else{
return mid;
}
}
return -1;
}
}
输入7