关闭

java基础学习笔记5

标签: java基础编程编码java
365人阅读 评论(0) 收藏 举报
分类:
java基础学习笔记6
    一、笔记内容概述:
        数组-第二种定义格式、数组-常见操作-遍历-最值-选择排序-冒泡排序-排序位置置换代码提取、数组-排序的性能问题、数组-常见功能-查找-折半查找、进制转换-查表法-整合。
    二、常用内容介绍:
        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();
	}
}





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:73570次
    • 积分:1347
    • 等级:
    • 排名:千里之外
    • 原创:43篇
    • 转载:114篇
    • 译文:0篇
    • 评论:3条
    最新评论