一、笔记内容概述:
数组-第二种定义格式、数组-常见操作-遍历-最值-选择排序-冒泡排序-排序位置置换代码提取、数组-排序的性能问题、数组-常见功能-查找-折半查找、进制转换-查表法-整合。
二、常用内容介绍:
- 1.数组初始化的三种方式:
int[] arr = new int[3];
int[] arr = new int[]{1,2,3};
int[] arr = {1,2,3};
- 2.查表法:
如果数据中出现了对应关系,而且对应关系的一方是有序的数字编号,并作为角标使用,这时就必须想到数组的使用(后面也可以使用map集合),这时就可以将这些数据存储到数组中,根据运算的结果作为角标直接去查数组中对应的元素即可,这种方法称为:查表法。
- 3.右移动作>>运算速度快,下面两个等价。
mid = (max+min)/2; mid = (max+min)>>1;
三、经典示例及讲解:
- 1.选择排序算法:
package com.date5;
/**
*选择排序思路: (可以根据确定最大值来排序,也可以根据确定最小值来进行排序,这里采用最小值)
* 1.首先拿数组第一个元素依次与除其自身外的其它每个元素顺序比较,
* 如果第一个元素大于剩下的某个元素,就互换内容。
* 2.经过一轮比较之后,此时,第一个元素就是数组中最小的元素。然后
* 再拿第二个元素与除第一个元素和其自身外的其它进行比较,如果第
* 二个元素大于剩下的某个元素,就互换内容。此时,第二个元素就是数
* 组中倒数第二小的元素。
* 3.依次类推,直到最后一个元素。
*
* 4.下面的Mysort方法之所以不用返回int数组的原因为:arr引用变量是
* 对传入Mysort方法中作为参数的数组的引用,Mysort方法执行完毕之后,
* 我们依然可以通过arr引用变量操作传入的数组。所以,没有必要再通过返回值获取。
*/
public class Demo3 {
private static int count = 0;
public static void main(String[] args){
int[] arr = {89,34,-270,17,3,100};
System.out.print("排序前数组: ");
printArray(arr);
Mysort(arr);
System.out.print("排序后数组: ");
printArray(arr);
System.out.println("交换总次数为:"+count);
}
//对数组进行排序
public static void Mysort(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]){
change(arr,i,j);
count++;
}
}
}
}
//交换函数
private static void change(int[] arr,int i,int j){
//使用^异或运算符
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
/*
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
*/
}
//打印数组
private static void printArray(int[] arr) {
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
System.out.println(","+arr[i]+"]");
break;
}
if(i==0) System.out.print("["+arr[i]);
else
System.out.print(","+arr[i]);
}
}
}
- 2.选择排序算法优化:
package com.date5;
/**
*效率分析:
* 选择排序算法优化,因为选择排序一轮比较的结果就是获取最小值
* ,所以我们没必要在这轮比较中,调用多次交换方法,只需要用一个变量
* 记录这一轮比较下来的最小值num和它的角标index,最后在比较,如果这个最小值
* 就是其本身,那么连一次调用交换方法的必要都没有了,这样以减少交换次数的方式
* ,理论上提高了效率,我定义一个变量count来记录两个传统方式和这种方式的效率情况。
*/
public class Demo4 {
//定义一个全局变量来记录交换的次数
private static int count = 0;
public static void main(String[] args) {
//1.初始化数组
int[] arr = {89,34,-270,17,3,100};
System.out.print("排序前:");
arr_print(arr);
//2.调用排序方法
my_sort(arr);
System.out.print("排序后:");
//3.打印结果
arr_print(arr);
System.out.println("交换总次数为:"+count);
}
private static void my_sort(int[] arr) {
for(int i=0;i<arr.length-1;i++){
//记录下当前进行比较的自身值和角标
int num = arr[i];
int index = i;
for(int j=i+1;j<arr.length;j++){
//将最小值和其角标记录下来
if(num>arr[j]){
num = arr[j];
index = j;
}
}
//如果最小值就是其本身,就不执行交换操作,否则执行
if(i!=index){
change(arr,i,index);
count++;
}
}
}
//交换函数
private static void change(int[] arr, int i, int index) {
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
//打印函数
private static void arr_print(int[] arr) {
System.out.print("[");
for(int i=0;i<arr.length;i++){
if(i!=arr.length-1){
System.out.print(arr[i]+",");
}else{
System.out.println(arr[i]+"]");
}
}
}
}
- 3.折半查找算法(又称为二分查找法)
package com.date5;
/**
*二分查找算法:(建立在有序数组基础上的快速查找元素的方法)
* 1.设置三个变量记录角标:min、max、mid,min初始化值为0,max为数组最大角标,mid为
* (max+min)/2。
* 2.查看mid角标的元素是否与待查找的值相等,如果相等,则直接返回角标值,程序终止执行。
* 3.如果待查找的值小于角标为mid的元素值,那么说明待查找的元素的位置可能在min和mid角标
* 之间,重新设置max = mid-1,mid = (max+min)/2,重复第1、2步的操作
* 4.如果待查找的值大于角标为mid对应角标的元素值,那么说明待查找的元素的位置可能在mid与max
* 之间。设min = mid +1,mid = (max+min)/2,重复第1、2步的操作。
* 5.如果数组中不存在待查找的元素,那么按照如上流程,最终min角标值会大于max角标值,此时返回
* -1。
*/
public class Demo6 {
public static void main(String[] args){
int[] arr = {1,2,3,4,5,6,7,8,9};
int index = MybinarySearch(arr,10);
System.out.println("对应的角标是:"+index);
}
public static int MybinarySearch(int[] arr,int x){
int max = arr.length-1;
int min = 0;
int mid = (max+min)/2;
//定义一个返回值
int temp = 0;
//只要它跟查找的值不一样就执行这个循环
while(arr[mid]!=x){
//如果所查找的那个数比中间值大
if(arr[mid]<x){
min = mid + 1;
}
//如果所查找的那个数比中间值小
if(arr[mid]>x){
max = mid - 1;
}
mid = (max+min)/2;
//如果这个有序数组中没有该元素,就返回-1
if(min>max){
return -1;
}
}
return mid;
}
}
- 4.获取一个十进制的2、8、16进制的表现形式
package com.date5;
/**
*获取一个十进制的2、8、16进制的表现形式
*注意:
* 如果数据出现了对应关系,而且对应关系的一方是有序的数字编号,并作为
* 角标使用,这时候必须要想到数组的应用。
*思路:
* 1.首先判断如果传入的十进制数为0,那么它的2、8、16进制都是0,直接返回
* 0,不需要再执行余下的程序。
* 2.如下面的所示,以将十进制数转换成十六进制数为例:
* 将60与15进行与操作,其值就是60的十六进制的最低位。
* 再将60无符号右移4位,再与15进行与操作,其值就是60的十六进制的倒数第二位。
* 3.由上面的例子可以总结出,将一个十进制数转换为十六进制的步骤就是:
* 将十进制数与15相与,将结果存储到一个数组的最低位。
* 然后将十进制数右移4位,再与15进行与操作,其值就是该数对应的十六进制的倒数
* 第二位。
* 再右移4为,与15相与,直到相与结果为0为止。
* 4.进而可以推理得到,10进制转换为2和8进制的规律与转换为16进制很相似,只是偏移
* 量和相与的数字不同而已。
* 10进制转换为2进制的偏移量为1,相与数字为1.
* 10进制转换为8进制的偏移量为3,相与数字为7.
*/
public class Demo7 {
public static void main(String[] args){
toHex(60);
toBin(-6);
}
public static void toBin(int num) {
//十进制转换成二进制相与数字为1,偏移量为1
trans(num,1,1);
}
public static void toHex(int num) {
trans(num,15,4);
}
//通用转换方法
public static void trans(int num, int base, int offset) {
if(num == 0){
System.out.println("0");
return;
}
char[] chs = {'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F'};
//创建一个数组来存放转换后的结果
char[] arr = new char[32];
//记录当前pos所移到的角标
int pos = arr.length;
while(num!=0){
int temp = num & base;
//从最高位开始存
arr[--pos] = chs[temp];
//无符号右移
num = num >>> offset;
}
System.out.println("pos="+pos);
for(int x = pos;x<arr.length;x++){
System.out.print(arr[x]);
}
System.out.println();
}
}
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:543120397 我们一起学Java!