(4)数组

1.定义函数首先明确函数需要返回什么结果,即返回值类型,其次明确函数运算过程中需要参与的未知变量,即形式参数类型和个数。定义函数只需完成需要的功能即可,不需要打印返回结果,需要对返回值进行打印还是比
较等运算是函数调用者的事,不要在函数定义时完成额外的功能,依需求而定。
2.数组定义:元素类型  [ ] 数组名=new 元素类型[数组长度或元素个数]
java虚拟机运行时,把内存划分为5块区域:栈、堆、方法区、本地方法区、寄存器。
基本数据类型int x=5;直接在栈内存中开辟一块内存空间,把变量名和值5存进去;
引用数据类型int [ ] y=new int [3];在栈内存中开辟一块空间,把数组名y存进去,通过new在堆内存中开辟一个连续的3块内存空间,把首元素的空间的地址赋值给y,如0X63DE,形成指向关系。
栈内存的特点:用于存储局部变量,当数据使用完时,所占内存自动释放;
堆内存的特点:1.必须有至少一块栈内存指向它,否则就是垃圾内存
              2.堆中的元素都有初始化值
              3.成为垃圾内存后,会在不确定的时间内被垃圾回收器回收
3.数组的常用操作:获取数组中的元素,数组的遍历,获取数组中的最大值、最小值(用一个变量存贮数组中的任一个元素,在遍历数组时,用其动态存储与当前获取元素的比较后的最大值,注意这个变量初始化可以是数组中的任意一个元素值,也可以是0,但此时变量用于存储数组的下标)
4.数组的排序:选择排序法、冒泡排序法  Array.sort(arr)
选择排序:从第一个数开始,依次与后面的所有数进行比较,再拿第二个数依次与后面的数进行比较;
冒泡排序:拿第一个数与第二个数比较,再拿第二个数与第三个数比较,依次比较两个相邻的数。
这两种排序的效率都不高,效率高的是希尔排序。
因为在堆内存中交换数据比较耗资源,高效率的方法是在栈内存中用一个变量存储需要交换的数,当一次循环结束后,再在栈内存中交换数据,这样每循环一次只发生一次堆数据交换。
/*------------------------------------------------------------*/
5.数组排序
  选择排序法,从数组的第一个元素开始,依次与后面的元素比较,前者>后者,二者值交换,所以内循环进行一次,最小值出现在最前面
    public static void selectSort(int [] arr){
        for (int x=0;x<arr.length-1 ;x++ )
{   //这里应该是减1的,防止下标越界,但奇怪不减1竟然正常运行,
                                             //因为当x=arr.length时,内循环y=x+1=arr.length,不满足      //y<arr.length,
            for (int y=x+1;y<arr.length ;y++ )
{    //所以跳出循环,就不会发生下标越界了
                    if (arr[x]>arr[y]) 
            //这个其实还是好理解的,外循环控制着当前比较着后     //面至少还有一个数,
                                                         //
所以外循环从0到arr.length-1
                        int temp=arr[x];                 //内循环控制从外循环的当前循环后紧接着的1位即 //x+1开始,
                        arr[x]=arr[y];                  //
直到最后1位,依次和和外循环当前的数比较     
                       arr[y]=temp;
                    }
                }
            }
    }
    //遍历数组并打印
    public static void printArr(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]+"]");
        }
    }
       冒泡排序法:从数组前两个数开始比较,如果前者>后者,二者交换顺序,然后从第二个数开始,第二个数与第三个数比较,依次滚动向前,比较相邻的两个数,循环一次后,最大数出现在最右端。
    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]>arr[y+1])
{
                    int temp=arr[y];
                    arr[y]=arr[y+1];
                    arr[y+1]=temp;
                }
            }
        }
    }
}
class ArraySort1{
    public static void main (String [] args){
        int [] arr={34,66,2,6,10,7};
        selectSort(arr);
        printArr(arr);
        bubbleSort(arr);
        printArr(arr); 
    }

选择排序法是每次固定一个数作为参照物,依次和后面的比较,走过后不再回头
冒泡排序法是每次比较相邻的两个数,两个两个比较,一遍过后从头再来,只是,比较的范围从右端一点点向左移
共同点,外循环一样,都要保证下标<arr.length-1,内循环通过一个判断交换值,(再次联想到交换两个数值得三种方法)
/*------------------------------------------------------------*/
6.数组查找
  遍历查找(查找一个数在数组中第一次出现的位置)
class ArraySearch1{
    public static void main (String [] args){
        int [] arr={4,7,2,67,2,32,90};
        System.out.println(getIndex(arr,2));
    }

public static int getIndex(int [] arr,int value){
        for (int i=0;i<arr.length ;i++ ){
            if (value==arr[i])       //i=0,满足i<arr.length,判断是否value=arr[i],如果不等,加1继续循环
                return i;           //如果相等,则返回i,return是函数结束的标志,返回i后函数结束
        }                          //如果直到i=arr.length,仍然没有value=arr[i],则跳出for循环,继续执行
        return -1;                //下面语句  注意,return-1不能写在for循环中
    }
}
/*------------------------------------------------------------*/
折半查找比遍历查找效率要高一点
//先把数组按升序排列,找出中间的数与指定的数比较,如果中间的数比指定的数小,则缩小查找范围
//再在剩下的范围中折中查找,依次循环,直到找到这个数或者查找范围的区间的下标交叉时,程序结束
class ArraySearch2{
    public static void main (String [] args){
        int [] arr={1,2,4,5,7,8,9};
        int index=halfSearch(arr,9);
        System.out.println("index="+index);
        int index2=halfSearch_2(arr,5);
        System.out.println("index="+index2);
    }

public static int halfSearch(int [] arr,int value){
        int min,max,mid;
        min=0;                                     //小角标
        max=arr.length-1;                    //大角标
        mid=(min+max) >>1;              //区间一半处的角标
        while (value!=arr[mid])
{             //当要找的数不等于中间角标时,一直缩小范围循环比较
            if (arr[mid]<value)               //要找的数大于中间角标的数,就缩小区间,在右半边区间中找
                min=mid+1;
            else if (arr[mid]>value)       //要找的数小于中间角标的数,就缩小区间,在左半边区间中找
                max=mid-1;
            if (min>max)                      //如果小角标移到大角标的右边了,说明要找的数不在数组中
                return -1;
            mid=(min+max)>>1;           //角标每移动一次,就折半一次
        }
        return mid;
    }
/*------------------------------------------------------------*/
//折半查找第二种循环逻辑
public static int halfSearch_2(int [] arr,int value){
        int min,max,mid;
        min=0;
        max=arr.length;
        mid=(min+max) >>1;
        while (min<max) 
{                             //当小角标一直在大角标左边时,还需要循环
            if (value>arr[mid])                 
                min=mid+1;
            else if (value<arr[mid])
                max=mid-1;
            else 
                return mid;
            mid=(min+max)>>1;
        }
        return -1;
    }
}
/*------------------------------------------------------------*/
需求:已知一个排过序的数组,当把一个数插入数组中后,仍然使数组按顺序排列,找出这个数的位置。
分析:这是折半查找的一个应用,当数组中存在与要插入的数相等时,返回该数的下标,当不存在时,返回 arr[min]的下标min
class ArraySearch3{
    public static void main (String [] args){
        int []arr={1,2,4,5,6,8,10,13};
        int index=halfSearchApp(arr,3);
        System.out.println(index);
    }

    public static int halfSearchApp(int [] arr,int value){
        int min,max,mid;
        min=0;
        max=arr.length-1;
        mid=(min+max)>>1;

        while (min<max){
            if(value>arr[mid])
                min=mid+1;
            else if(value<arr[mid])
                max=mid-1;
            else 
                return mid;
            mid=(min+max)>>1;
        }
            return min;
    }
}

7.进制转换(优化后的代码)
public class Test{
public static void main(String []args){
toBin(6);
toBin(-6);
toOct(60);
toHex(60);
}
}
//十进制转换为二进制
public static void toBin(int sum){
trans(num,1,1);
}
//十进制转换为八进制
public static void toOct(int sum){
trans(num,7,3);
}
//十进制转换为十六进制
public static void toHex(int sum){
trans(num,15,4);
}
//进制转换提取出的通用代码
public static void trans(int num,int base,int offset){
//如果是0,直接打印并结束
if (num==0) {
  System.out.println(0); 
  return; 
  }
//定义查表用的数组
char [] chg={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//定义一个存储转换后的字符的数组
char [] arr=new char [32];
//定义存储结果时的指针
int pos=arr.length;
while(num!=0){
  int temp=num & base;   //取num最低base位
  arr[--pos]=chg[temp];    //查表后存储到arr中
  num=num >>>offset;     //num无符号右移offset位
}
//遍历,打印
for (int x=pos;x<arr.length;x++){     //从pos开始打印,避免前面出现0
    System.out.print(arr[x]);
}
System.out.println();   //换行
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值