java方法的可变参数数组复制排序分类冒泡和选择排序搜索等常用方法实现

Posted 抛物线.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java方法的可变参数数组复制排序分类冒泡和选择排序搜索等常用方法实现相关的知识,希望对你有一定的参考价值。

java方法的可变参数、数组复制、排序分类、冒泡和选择排序等常用方法实现

  由于代码的可观性,下面分别以图片和文字形式展现:以下内容有些繁多,因为涉及内容过多,
  源代码也以两种形式贴上去了。

①增强型for循环




增强for循环-foreach:
需求:定义一个数组,使用循环迭代出数组中的每一个元素.
使用for循环的操作如下:





其实,我们在使用循环迭代数组的时候,往往是不关心迭代变量(数组的索引),有没有更好的方式,迭代数组元素的时候,就只操作数组元素,不去操作数组的索引.
从Java5开始(JDK1.5)开始,Java提供了一种新的语法:增强for循环(foreach).
语法:
for(数组元素类型 变量  :   数组名)

       循环体

-----------------------------------------------------------
通过反编译工具查看字节码,发现foreach其实在底层依然是使用for循环+索引来操作数组的.
我们把增强for循环,称之为编译器的新特性---->语法糖.
语法糖的最大甜头就是:让开发者写更少,更简单的代码,完成相同的功能.
-----------------------------------------------------------
for循环功能比foreach更彪悍.
------------------------------------------------------------
如果迭代数组元素,而不关心数组的索引的时候,首选使用foreach.
-----------------------------------
foreach还未结束--->集合框架.


public class ForEach 
    public static void main(String[] args) 
        int [] arr=new int [] 10,20,30,40,50;
        printArr1(arr);
        printForEachArr(arr);
    
    public  static  void printArr1(int [] arr)
        for (int index=0;index<arr.length;index++)
            System.out.println(arr[index]);
        
    
    //通过反编译 我们可以看到 foreach底层使用的仍然是for循环+索引来操作数组的
   /* for (数组元素类型  变量:数组名)
    
        循环体
    */
    public static void printForEachArr(int [] arr)
        for (int ele:arr)
            System.out.println(ele);
        
    


 定义数组,给数组元素赋值.当取出数组中的元素值的时候,咱们会使用循环(while,do while,for)来操作,该操作,称之为循环遍历,但是循环变量是数组的索引.





 此时的操作,没有问题,但是,我们压根就不关心数组的索引,我们只关系数组的元素是多少.
 从Java5开始,提供了增强for循环(for-each),就可以直接地取出数组中的每一个元素.
 语法:
      ------------------------------------------
 for(元素类型 变量 : 数组名)
 
     变量就表示每一个元素值
 
 ------------------------------------------

增强for循环,其实是一个语法糖(编译器级别的新特性),但是在字节码中/底层依然是for循环.
那到底,咱们是使用for循环还是使用增强for循环?
若需要取出数组元素,则使用for-each更简单.
但是若需要操作数组索引,就只能使用普通的循环.



public class VarArgsDemo 
    public static void main(String[] args) 
//        double [] arr=new double [] 10.0,20.0,30.0,40.0,50.0;
        double sum=getSum(0.8,10.0,20.0,30.0,40.0,50.0);
        System.out.println(sum);

    
    public static double getSum(double cutoff,double ... arr)
        double sum=0.0;
        for (double price : arr)
             sum += price;
        return sum * cutoff;
    

②数组的copy

 数组拷贝:
从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。
被复制的组件的编号等于 length 参数。
源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。
public static void arraycopy(int[] src, int srcPos, int[] dest,int destPos, int length) 

 定义一个数组元素的拷贝方法,能支持任意类型的数组元素拷贝操作(反射).
 数组拷贝操作,是经常使用到的,SUN就直接把数组的拷贝操作存放在JDK中的System类中.
 Object:Java语言中的根类,老祖宗类,Object可以表示任意数据类型.
 该方法没有方法体,该方法使用了native修饰符(本地方法),该方法底层使用了C/C++语言实现了,Java直接调用其他语言编写好的功能:


 查阅API文档了(Java的帮助文档/好比字典).,在什么类中有什么功能的方法即可,文档在手,天下我有!.




public class ArrayCopy 
    public static void main(String[] args) 
        int [] src = new int [] 1,2,3,4,5,6,7,8,9,10;
        int [] dest = new int [10];
        printArry(dest);
//        copy(src,2,dest,5,4);
//        printArry(dest);
        System.arraycopy(src,2,dest,5,4);
        printArry(dest);
    

    static void copy(int [] src,int srcPos,int [] dest,int destPos, int length)
    
        if (srcPos<0 || destPos<0 || length <0 || srcPos+length>src.length)
            System.out.println("不合理");
        
        /*
        dest[destPos]=src[srcPos];
        destPos++;
        srcPos++;
        dest[destPos]=src[srcPos];
        destPos++;
        srcPos++;
        dest[destPos]=src[srcPos];
        destPos++;
        srcPos++;
        dest[destPos]=src[srcPos];
        destPos++;
        srcPos++;
        */

        for (int index=srcPos;!(index>=srcPos+length);index++)
        
            dest[destPos]=src[index];
            destPos ++;
        
    

    static void  printArry(int [] arr)
        if (arr==null)
            System.out.println("null");
            return;
        
        String ret="[";
//        for (int ele : arr)
//            System.out.println(ele);
//        
        for (int index = 0; !(index >= arr.length); index++)
        
            ret=ret+arr[index];
            if (index!=arr.length-1)
            
             ret=ret+",";
            
        
        ret=ret+"]";
        System.out.print(ret);
    



③:排序问题

排序的分类:
选择排序(直接选择排序、堆排序)
交换排序(冒泡排序、快速排序)
插入排序(直接插入排序、二分法插入排序、Shell排序)
归并排序等。--------------------------------------------------------------
排序有升序排列和降序排列之分,我们现在单讲升序排列:

 排序:按照指定的顺序排列出来.
   升序:从小到大:
   降序:从大到小.
   --------------------------------------------
  排序的分类:
  选择排序(直接选择排序、堆排序)
  交换排序(冒泡排序、快速排序)
  插入排序(直接插入排序、二分法插入排序、Shell排序)
  归并排序等。
  排序有升序排列和降序排列之分,我们现在单讲升序排列:
  我们主要讲解冒泡,选择,插入排序,当然在开发中因为性能问题,我们都不会自己写排序算      法,不过排序在笔试题里却是常客。

  若有下列int类型数组需要排序:
  int[] arr = 2,9,6,7,4,1;

 冒泡排序(Bubble Sort):
 这是最简单的排序法,基本思路:
 对未排序的各元素从头到尾依次比较相邻的两个元素大小关系,若大于则交换位置,经过第一轮比较排序后可得出     最大值,然后使用同样的方法把剩下的元素逐个比较即可。
 可以看出若有N个元素,那么一共要进行N-1轮比较,第M轮要进行N-M次比较。(若6个元素,要进行6-1轮比较,第一轮比较6-1次,第三轮比较6-3次)。

④选择排序

     选择排序(Selection Sort):
     基本思路:选择某个索引位置的元素,然后和后面元素依次比较,若大于则交换位置,经过第一轮比较排序后可         得出最小值,然后使用同样的方法把剩下的元素逐个比较即可。
     可以看出选择排序,第一轮会选出最小值,第二轮会选出第二小的值,直到最后。
     第一轮从arr[0]和后面元素相比较,第二轮从arr[1]和后面的元素相比较,依次类推。N个数要进行N-1轮。选择排序每一轮只进行一次交换,相对于冒泡排序效率高一些。


完整的选择排序整个实现过程

public class selectSort 
    public static void main(String[] args) 
        int[] arr = new int[]2, 4, 3, 9, 5, 1, 8;
//        BubbleSortDemp.printArr(arr);
        selectSort1(arr);
        BubbleSortDemp.printArr(arr);
    

    public static void selectSort1(int[] arr) 

       /*
        for (int i = 1; i <= arr.length - 1; i++) 
            if (arr[0] > arr[i]) 
                BubbleSortDemp.swap(arr, 0, i);
            
        
        for (int i = 2; i <= arr.length - 1; i++) 
            if (arr[1] > arr[i]) 
                BubbleSortDemp.swap(arr, 1, i);
            
        
        for (int i = 3; i <= arr.length - 1; i++) 
            if (arr[2] > arr[i]) 
                BubbleSortDemp.swap(arr, 2, i);
            
        
        */


//        for (int times=1;times<=arr.length-1;times++)
//        
//            for (int i=times;i<=arr.length-1;i++)
//            
//                if (arr[times-1]>arr[i])
//                
//                    BubbleSortDemp.swap(arr,times-1,i);
//                
//            
//        


        for ( int times=0;times<=arr.length-1;times++)
        
            int minIndex=times;
            for (int i=times+1;i<arr.length;i++)
            
                if (arr[minIndex]>arr[i])
                
                    minIndex=i;
                
            
            BubbleSortDemp.swap(arr,times,minIndex);
        
    

    #####这是真正的选择排序算法
static void selectSort(int[] arr) 
	for (int times = 0; times < arr.length - 1; times++) 
		int minIndex = times;
		for (int i = times + 1; i < arr.length; i++) 
			if (arr[i] < arr[minIndex]) 
				minIndex = i;
			
		
		swap(arr, times, minIndex);
	





###这是冒泡排序的算法

public class BubbleSortDemp 
    public static void main(String[] args) 
      /*
      object:java语言中的根类,老祖宗类,object可以表示任意数据类型
                该方法没有方法体,该方法使用了native修饰符(本地方法),该方法底层使用了C/C++语言实现了
            java直接调用其他语言编写好的功能

       */
//      System.arraycopy();
        int [] arr = new int [] 2,4,3,9,1,5,7;
        printArr(arr);
        bubbleSort1(arr);
        System.out.println("\\n");
        printArr(arr);
    
    public static void printArr(int [] arr)
        for (int ele: arr)
            System.out.print("  "+ele);
        

    
    public static void bubbleSort1(int [] arr)
        for (int i=0;i<arr.length-1;i++)
            for (int j=0;j<arr.length-i-1;j++)
                if (!(arr[j]<=arr[j+1]))
                
                    swap(arr,j,j+1);
                
            
      //            System.out.println("第"+(i+1)+"轮排序后:");
      //            printArr(arr);
        
       
    public static void swap(int [] arr,int index1,int index2)
        int temp=arr[index1];
        arr[index1]=arr[index2];
        arr[index2]=temp;
      
     





⑤▁▁▁▂▂▃▃▄▄搜索算法

  数组的搜索算法:从指定数组中去搜索某一个元素的索引是多少.

   方式1:线性搜索(从头搜到尾/从尾搜到头):indexOf/lastIndexOf
          对于元素过多的数组,性能极低:有N个元素,循环次数= (N + 1) / 2;

    方式2:二分搜索法/二分查找法/折半查找.
           前提:数组元素必须有顺序.

  算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的

  猜数游戏:

  一个朋友让你猜他正在想的一个从1到100之间的数,等你猜了,他会告诉你三种结果中的一个:你猜的比他想的大,或小,或猜中了。

  为了能用最少的次数猜中,必须从50开始猜。如果他说你猜的小了,那么就能推出哪个数在50到100之间,
  所以马上猜75。但如果他说猜大了,你也能明白哪个说在1到50之间,所以马上猜25。
  如此重复,范围越来越小,直到猜到为止。





需求:从某一个数组中,查询出某一个元素的索引位置.

查找元素:
   1):线性查询(从前往后查找,或者从后往前查找).
  该方式,性能极低,如:数组中有10万个元素,刚好需要查询的元素在最后一个,此时就得循环10万次,才能找到.
   2):二分法查找(折半查找):
          前提:必须有序.

算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的

猜数游戏:

一个朋友让你猜他正在想的一个从1到100之间的数,等你猜了,他会告诉你三种结果中的一个:你猜的比他想的大,或小,或猜中了。


搜索算法的简单基础实现:

public class searchArr 
    public static void main(String [] args)
        int [] arr=10,20,30,40,10,20,60,10,15,-10,19,10;
        int beginIndex=searchArr.indexOf(arr,10);
        System.out.println(beginIndex);
        int lastIndex=searchArr.lastIndexOf(arr,19);
        System.out.println(lastIndex);
    
    public static int indexOf(int arr [],int key)
        for (int index=0;index<arr.length;index++)
//            System.out.println(arr[index]);
            if (arr[index]==key)
                return index;
            
        
        return -1;
    
    public static int lastIndexOf(int arr[],int key)
        for (int index=arr.length-1;index>=0;index--)
            if (arr[index]==key)
                return index;
            
        return -1;
    





1)二分类查找算法

	public class binarySearchDemo 
    public static void main(String[] args) 
        int [] arr = new int[] 1,2,3,4,5,6,7,8,9;
        int value = binarySearch(arr,3);
        System.out.println(value);
    
    public static int binarySearch(int [] arr,int key)
        int low = 0;
        int high = arr.length-1;
        while (low <= high)
        
            System.out.println(low+"---------------"+high);
            int mid = (low+high) >> 1;
            int midVal = arr[mid];
            if (midVal > key)
            
                high = mid - 1;
            else if (midVal < key)
            
                low = mid + 1;
            else
            
                return mid;
            
        return -1;
      
     


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190512153322512.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI4NTEzODAx,size_16,color_FFFFFF,t_70)


⑥ 搜索特定的数值对应的第一个索引和最后一个索引

```java
public class arr1 
    public static void main (String [] args)
        int [] arr=1,12,3,3,4,12,12,45,34,124,4523,1231,12;
        int firstArr=indexOf(arr,12);
        System.out.println(firstArr);
        int lastArr=lastIndexOf(arr,12);
        System.out.println(lastArr);
        System.out.println(arr.length);


    
    public static int indexOf(int [] arr,int key)
        for (int index=0;index<arr.length;index++)
            if (arr[index]==key)
                return index;
            
        return -1;
    
    public static int lastIndexOf(int [] arr,int key)
        for (int index=arr.length-1;index>=0;index++)
            if (arr[index]==key)
                return index;
            
        return -1;
    


 总结:
 讨论的都是int类型数组:
 打印数组元素:print方法
 颠倒数组元素:reverse
 获取元素索引:indexOf/lastIndexOf
 获取元素最值:getMax/getMin

以上是关于java方法的可变参数数组复制排序分类冒泡和选择排序搜索等常用方法实现的主要内容,如果未能解决你的问题,请参考以下文章

冒泡排序和选择排序

Java常识7.0 数组实现冒泡排序选择排序和二分查找

Java常识7.0 数组实现冒泡排序选择排序和二分查找

冒泡排序和选择排序

Java排序算法分析与实现:快排冒泡排序选择排序插入排序归并排序

总结4种常用排序(快排选择排序冒泡排序插入排序)