1.定义函数首先明确函数需要返回什么结果,即返回值类型,其次明确函数运算过程中需要参与的未知变量,即形式参数类型和个数。定义函数只需完成需要的功能即可,不需要打印返回结果,需要对返回值进行打印还是比
较等运算是函数调用者的事,不要在函数定义时完成额外的功能,依需求而定。
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(); //换行
}
}