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

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; //找不到的情况

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值