数组

数组

可变参数
  • 提高代码的复用性
  • 简化了开发、降低入参的复杂度
  • 可变参数作为形式参数一定是在当前形参的最后
  • 可变参数作为形式参数一定只有一个
  • 可变参数在一定长度上可以代替相同类型不同个数的方法重载
public class Test {
    public static void main(String[] args) {
        //调用该方法会出现什么问题
        //fun("",null);
    	invoke(null,1);//会调用哪个方法呢? 
    }

    public static void fun(String str,String ... strs){
        System.out.println("str = [" + str + "], strs = [" + strs + "]");
    }
    public static void fun(String str,Integer ... ins){
        System.out.println("str = [" + str + "], ins = [" + ins + "]");
    }
    
    static void invoke(Object obj,Object ... args ){
        System.out.println("obj = [" + obj + "], args = [" + args + "]");
    }
    static void invoke(String str,Object obj,Object ... args){
        System.out.println("str = [" + str + "], obj = [" + obj + "], args = [" + args + "]");
    }    
}
运行结果:第一个出现编译错误
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method fun(String, String[]) is ambiguous for the type Test
解析:null可以转换为任意类型,String和Integer都是同级的引用类型,系统不知道运行哪个所以会出编译错误

第二个运行的是下面的invoke(String str,Object obj,Object ... args)
str = [null], obj = [1], args = [[Ljava.lang.Object;@15db9742]
解析:下面2种方法单独调用时都没有问题,之所以调用后者还是因为最近最优原则,null先转换为String类型,才能转化为Object类型,因为Object类型是String的父类,所以会优先调用String
排序算法(冒泡排序)

冒泡排序是一种非常容易理解的排序算法,总共比较n-1趟,每趟从起始元素位置开始,两两相邻的元素互相比较,一直比较到最后一个数,这样一趟下来,最后一个数要么是最大数,要么是最小 数。持续以上的步骤,直到整个数组排完序。冒泡排序的时间复杂度为0(n^2),但是可以通过优化提高速度。

没优化的代码:

public static void bubbleSort01(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<arrs.length-1;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
				}
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}		
		}	
	}
//比较n-1趟,每趟都从首个元素开始比较,要执行n-1次,总共执行(n-1)^2次,效率很低

优化方案1:

public static void bubbleSort02(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<arrs.length-1-i;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
				}
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}
		}	
}
//比较的趟数相同,但是每次比较的次数会减少一次

优化方案2:

public static void bubbleSort03(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			//声明一个是否排好序
			boolean isSorted = true;
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<arrs.length-1-i;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					isSorted = false;
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
				}
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}	
			//判定
			if(isSorted) {
				break;
			}	
		}	
	}
//给定一个boolean型变量,如果本趟遍历没有交换(说明已经排好序),那么从下趟开始不再执行循环。从而减少总的趟数。

优化方案3:

public static void bubbleSort04(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		//基准点
		int index = arrs.length-1;
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			//声明一个是否排好序
			boolean isSorted = true;		
			int tmp = 0; 
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<index;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					isSorted = false;
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
					tmp = j;
				}			
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}
			index = tmp;
			//判定
			if(isSorted) {
				break;
			}		
		}		
	}
//相比前一种方法,这种方法添加了一个索引值,首先把索引指向最后一个元素,每趟执行完会把索引重新指向已经排好序的最前面的那个元素,这样如果数组后面出现多个已经升序排好的元素,可以减少每趟比较的次数,但是如果给定的数组是一个逆序的数组,这种方案没有任何价值。

方案4

鸡尾酒排序(双向冒泡排序),冒泡排序的最终优化方法,

注:鸡尾酒排序相比前面的方法会优化一些,它的思路是在一次循环中将本趟的最大值放到最后,最小值放到首位,然后分别把对应的索引改变,重复对中间的数组进行排序。虽然它的执行次数可能会减少一些,但是时间复杂度仍然是0(n^2),如果遇到逆序,效果极其差。

public static void cockTailsort(int[] arrs){
		int temp;
		int m=0,n=arrs.length-1;
		while(m<n){
			for(int i=m; i<n;i++){
				if(arrs[i]>arrs[i+1]){
					//交换数组中两个数字的位置
					temp=arrs[i];
					arrs[i]=arrs[i+1];
					arrs[i+1]=temp;
				}
			}
			n--;
			for(int i=n; i>m;i--){
				if(arrs[i]<arrs[i-1]){
					//交换数组中两个数字的位置
					temp=arrs[i];
					arrs[i]=arrs[i-1];
					arrs[i-1]=temp;
				}
			}
			m++;
		}	
	}
查找算法(二分查找)

该算法比较容易理解,并且效率较高。因为每次都是去掉一半数据进行查找,它的时间复杂度为0(logn).但是前提必须要保证数组中数据已经是有序的。如果该集合中频繁的插入或者是删除数据,那么维护有序的集合是一 件很麻烦的事情,就不建议使用了。

下面是一个简单的演示图。

如图,先把low指向第一个元素,high指向最后一个元素,mid指向low+high/2

如果目标值比mid小,high指向mid前一个元素,再次求mid的索引,(如果是目标值比mid更大,则把low指向mid后一个元素)直到找到目标值如果当low>=high,还没找到说明该数组里面不存在对应的目标值。

下面附上代码。

public static int binerySearch(int[] arrs,int target) {
		//声明索引
		int high = arrs.length-1;
		int low = 0;
		int mid = 0;
		//循环判定
		while(low<=high) {
			mid = (high+low)/2;
			if(arrs[mid]>target) {
				high = mid-1;
			}else if(arrs[mid]<target) {
				low = mid+1;
			}else {
				return mid;
			}
		}
		return -1;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值