java数组、排序算法、查找算法详解

来源:互联网 发布:nginx代理静态资源 编辑:程序博客网 时间:2024/05/16 18:59

1、为什么定义数组要采用type[] arrayName;这种方式?
     因为这种方式具有很好的可读性,使用这种方式很容易就可以理解这是定义一个变量,其中变量名是arrayName,变量的类型是type[]。


2、定义数组是为什么不可以指定数组的长度?
     我们知道数组是一种引用类型的变量,因此使用它来定义一个变量时,仅仅表示定义了一个引用变量(也就是定义了一个指针),这个引用变量还未指向任何有效内存,因此定义数组时不能指定数组的长度。
     因为定义数组只是定义了一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此这个数组也不能使用,只有对数组进行初始化之后才可以使用。


Arrays:针对数组进行操作的工具类。属于util包。没有构造方法。但是这个类的方法都是静态方法,可以通过类直接调用
public static String toString(T[] a):把数组转换成字符串
public static void sort(T[] a):对数组进行排序(底层是快速排序)
public static int binarySearch(T[] a,Tkey):二分查找

public class ArrayDemo {    public static void main(String[] args) {        int[] arr = {24,69,80,57,13};        System.out.println(Arrays.toString(arr));           //[24, 69, 80, 57, 13]        System.out.println(Arrays.binarySearch(arr, 57));   //-2(为什么呢?看后面的源码找答案)        Arrays.sort(arr);        System.out.println(Arrays.toString(arr));           //[13, 24, 57, 69, 80]        System.out.println(Arrays.binarySearch(arr, 57));   //2    }}

为了更加深刻的了解这些方法的原理,下面贴出源码以供理解:
这个是toString的源码:只要是对象,我们在使用之前都要判断是不是null,以防出现空指针异常

public static String toString(int[] a) {    if (a == null)        return "null";    int iMax = a.length - 1;    if (iMax == -1)        return "[]";    StringBuilder b = new StringBuilder();    b.append('[');    for (int i = 0; ; i++) {        b.append(a[i]);        if (i == iMax)            return b.append(']').toString();        b.append(", ");    }}

binarySearch的源码:

public static int binarySearch(int[] a, int key) {    return binarySearch0(a, 0, a.length, key);}private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {        int low = fromIndex;        int high = toIndex - 1;        while (low <= high) {            int mid = (low + high) >>> 1;            int midVal = a[mid];            if (midVal < key)                low = mid + 1;            else if (midVal > key)                high = mid - 1;            else                return mid; // key found        }        return -(low + 1);  // key not found.    }



冒泡排序
1、相邻元素两两比较,大的往后面放。
2、第一次排序完毕后,最大值就出现在了最大索引处。
3、第二次排序,最后一个索引的位置就不需要比较了
4、第三次排序,倒数第二个索引位置就不需要比较了

用i来表示比较的次数。每一次都会从索引为0的位置开始向后比较。
第一轮:i = 1,j 的范围是第一个到最后一个,所以j的索引范围是[0,arr.length-1](arr.length-1是数组最后一个位置的索引,看成一个整体)
              第一轮之后,会确定一个最大值。因此第二轮比较的时候就不用去比较这个最大值了。
第二轮:i = 2,因为第一轮已经确定了一个最大值,有1个元素不会参与比较。因此第二轮 j 的索引范围变成了[0,(arr.length-1)-1]
              第二轮比较之后,会确定两个应该在数组末尾的两个值。第三轮就不用去比较这两个值了。
第三轮:i = 3,因为第二轮已经确定了两个大值了,有2个元素不会参与比较。因此第三轮 j 的索引范围变成了[0,(arr.length-1)-2]
……..
依次类推:第 i 次 j 的索引范围应该是:[0,(arr.length-1)-(i-1)]
代码如下:

public class BubbuleDemo {    public static void main(String[] args) {        int[] arr = { 24, 69, 80, 57, 13 };        bubbleSort(arr);    }    // 冒泡排序    public static void bubbleSort(int[] arr) {        for (int i = 1; i <= arr.length - 1; i++) { // 控制比较的次数。次数 = 数组长度-1            for (int j = 0; j < (arr.length - 1) - (i - 1); j++) {                if (arr[j] > arr[j + 1]) {                    int temp = arr[j];                    arr[j] = arr[j + 1];                    arr[j + 1] = temp;                }            }        }        for (int i = 0; i < arr.length; i++) {            System.out.print(arr[i] + " ");        }    }}



选择排序
1、从索引为0的地方开始,依次和后面的比较,小的往前放
2、第一次比较从0索引开始往后比较。第一次比较完毕后,最小的元素就出现在了第一个位置上。
3、第二次比较的时候就不比较第一个元素了,就会从第二个元素开始比较。也就是第二次比较从1索引开始比较。
     第二次比较完毕后,第二小的就出现在了第二个位置上。
4、第三次比较的时候就不比较前两个元素了,就会从第三个元素开始比较.也就是第三次比较从2索引开始比较。
…….
第 n 比较的时候就不比较前(n-1)个元素了,会从第n个元素开始比较。也就是第n次比较从(n-1)索引开始比较。

public class SelectSort {    public static void main(String[] args) {        int[] arr = { 24, 69, 80, 57, 13 };        selectSort(arr);    }    public static void selectSort(int[] arr) {        for (int i = 0; i <= (arr.length - 2); i++) {  //已经确认好的值的个数,比如:确定了0个人,就从0索引开始依次跟后面的比较            for (int j = i + 1; j <= (arr.length - 1); j++) {                if (arr[i] > arr[j]) {                    int temp = arr[j];                    arr[j] = arr[i];                    arr[i] = temp;                }            }        }        for (int i = 0; i < arr.length; i++) {            System.out.print(arr[i] + " ");           //13 24 57 69 80         }    }}



二分查找(折半查找算法):数组元素有序的情况下
1、每次都去找中间的那个元素,跟要查找的元素比较,
2、如果中间元素的值 > 要查找的值,就在左半部分找
3、如果中间元素的值 < 要查找的值,就在右半部分找
注意:只有有序数组才可以使用这个方法。不可以对无序数组采用二分查找,不可以先排序再二分查找,因为你的数组元素都变了,你查找的索引已经不再是原始数组的索引了。

public class BinarySearch {    public static void main(String[] args) {        int[] arr = { 11, 23, 34, 46, 57, 68, 79, 80 };        System.out.println(binarySearch(arr, 57));         //4    }    //二分查找    public static int binarySearch(int[] arr, int value) {        int min = 0;        int max = arr.length - 1;        int mid = (max + min) / 2;        while (min <= max) {            if (arr[mid] > value) {                max = mid - 1;            } else if (arr[mid] < value) {                min = mid + 1;            }else{                return mid;            }            mid = (max + min) / 2;        }        return -1;      //找不到的情况    }}
原创粉丝点击