如何理解java数组的二分查找_<Java SE 详解>数组-二分查找-

1、数组(Array):相同类型数据的集合就叫做数组.

2、如何定义一个数组:

1>

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[4]; //定义数组的格式 }

}

从new可以看书,数组是一种对象类型.

type[] var = new type[len];

2>

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = {1, 2, 3, 4};

for (int i=0; i

{

System.out.println(a[i]);

}

}

}

3>

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[]{1, 2, 3, 4};  //这里第二个int[]方括号内不能加入数组元素的个数,否则会编译错误

for (int i=0; i

{

System.out.println(a[i]);

}

}

}

java中的每个数组对象都有一个名为length的属性,表示数组的长度。

length属性是public、final属性,无法修改其值。数组长度是在构造数组的时候在构造函数中确定的,一旦确定,就无法改变其大小。

3.

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = {1, 2, 3};

int[] b = {1, 2, 3};

System.out.println(a.equals(b)); //print false }

}

这里a数组和b数组指向了不同的内存地址,而不是想String那样存在一个String Pool,因此使用继承过来的equals方法比较的两个引用地址的值时不相同的。

int[] a = new int[4],其中a是一个引用,它指向了生成的数组对象的首地址,数组中每个元素都是int类型,其中仅仅存放数据本身

注意:Java中内存堆中的对象是不能直接进行操作的,而必须通过引用进行操作,而new关键字创建对象完成后就是返回了该对象的引用;因此在创建对象数组的时候,每个数组元素实际是一个引用变量,而不是堆内存中的对象。

关于数组的协变性:

协变的意义:当数组中的元素的类型时另一个数组的元素类型的子类的时候,该数组也是另一个数组的子类,这种意义就是数组的协变性;(泛型就不存在这种意义)

如下例:

packagecn.edu.bupt.observer.observable;public classArrayShiftTest

{public static voidmain(String[] args)

{

Number[] nums;

Integer[] ints;

ints= new Integer[2];

nums= ints; //自动类型转换成为父类数组, OK

System.out.println(ints instanceof Number[]); //print true

System.out.println("------------");

nums= new Number[2];

ints= (Integer[])nums; //强制转换成为子类型数组, OK 但运行时会发生错误

}

}

但是对于存在数组协变性的问题来说,更通常的做法是在遍历数组的时候取出数组中的每一个元素,对元素对象进行转换,这样避免了数据操作的不一致性;

具体关于协变的问题,请参见本博客关于泛型的讲解;

4.二维数组

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[][] i = new int[2][3];

System.out.println(i instanceof Object); //print true System.out.println(i[0] instanceof int[]); //print true }

}

注意:int[]是一种类型,代表一维数组类型,同样int[][]是二维数组类型,依此类推.

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

//二维数组初始化 int[][] a = new int[][]{

{1, 2, 3},

{4, 5},

{6, 7, 8, 9, 10}

};

for (int i=0; i

{

for (int j=0; j

{

System.out.print(a[i][j] + ",");

}

System.out.println();

}

}

}

其中,a.length是数组高维的长度,a[i].length是数组的指定低维的长度.

不使用中间变量实现两个整数的交换:

int a = 3;

int b = 4;

a = a + b;

b = a - b;

a = a - b;

System.out.println(a);

System.out.println(b);

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

I[] i = new I[]{new C(), new C()}; //含有两个引用元素的数组,这两个引用指向I类

}

}

interface I

{

}

class C implements I

{

}

java.util.Arrays相关函数用法:

判断数组相等的方法,java.util.Arrays

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[]{1, 2, 3};

int[] b = new int[]{1, 2, 3};

System.out.println(Arrays.equals(a, b));

}

}

数组copy

JDK中提供了两种类型的copy方法:

1.java.lang.System.arraycopy

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[]{1, 2, 3};

int[] b = new int[3];

System.arraycopy(a, 0, b, 0, 3);

for (int i=0; i<3; i++)

{

System.out.println(b[i]);

}

}

}

此处注意的是:目标数组b一定需要预先分配好空间,否则会发生异常。

2.java.util.Arrays.copyof

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[]{1, 2, 3};

int[] b = null;

b = Arrays.copyOf(a, 2);

for (int i=0; i<2; i++)

{

System.out.println(b[i]);

}

}

}

注意:同System.arraycopy方法不一样的是,目标数组b可以在调用处不分配空间,而是在copyof方法内部分配了数组的空间,在调用处需要做的工作是仅仅是声明一个数组的引用变量来接受copy好的数组。

三维数组:

type[][][] var = new type[m][n][k];

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart

{

public static void main(String[] args)

{

int[][][] a = new int[2][3][4];

System.out.println(a instanceof int[][][]);

System.out.println(a[0] instanceof int[][]);

System.out.println(a[0][0] instanceof int[]);

for (int[][] b : a)

{

for (int[] c : b)

{

for (int d : c)

{

System.out.print(d);

}

System.out.println();

}

System.out.println("------------");

}

}

}

冒泡排序:

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = {4,5,6,3,9,5,4,6,8,0};

ArrayStart.bubbleSort(a);

for (int b : a)

{

System.out.println(b);

}

}

private static void bubbleSort(int[] a)

{

int temp = 0;

for (int i=a.length-1; i>0; i--)

{

for (int j=0; j

{

if (a[j] > a[j+1])

{

temp = a[j];

a[j] = a[j+1];

a[j+1] = temp;

}

}

}

}

}

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = {4,5,6,3,9,5,4,6,8,0};

ArrayStart.bubbleSort(a);

for (int b : a)

{

System.out.println(b);

}

}

private static void bubbleSort(int[] a)

{

int temp = 0;

for (int i=0; i

{

for (int j=0; j

{

if (a[j] > a[j+1])

{

temp = a[j];

a[j] = a[j+1];

a[j+1] = temp;

}

}

}

}

}

二分查找(binary search):

二分查找的条件是:待查找的数组首先需要有序。

二分查找一般使用递归方法:

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[] { 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 15, 16, 19, 22,

23, 25, 27 };

int value = 14;

int index = binarySearch(a, 0, a.length-1, value);

System.out.println(index);

}

private static int binarySearch(int[] a, int startIndex, int endIndex, int value)

{

if (startIndex > endIndex)

{

return -1;

}

int index = (startIndex + endIndex) / 2;

if (value == a[index])

{

return index;

}

else if (value > a[index])

{

return binarySearch(a, index + 1, endIndex, value);

}

else

{

return binarySearch(a, startIndex, index - 1, value);

}

}

}

二分查找的非递归方法:

package cn.edu.bupt.array;

public class ArrayStart

{

public static void main(String[] args)

{

int[] a = new int[] { 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 15, 16, 19, 22,

23, 25, 27 };

int value = 17;

int index = binarySearch(a, value);

System.out.println(index);

}

private static int binarySearch(int[] a, int value)

{

int startIndex = 0;

int endIndex = a.length - 1;

int middle = 0;

while (startIndex <= endIndex)

{

middle = (startIndex + endIndex) / 2;

if (value == a[middle])

{

return middle;

}

else if (value < a[middle])

{

endIndex = middle - 1;

}

else

{

startIndex = middle + 1;

}

}

return -1;

}

}

题目:

随机生成 50 个数字(整),每的范围是 [10, 50],统计每个数字出现的次以及 出现次数以及出现次数最多的数字与他的个数,最后将每个数字以及其出现的次数打印出来,如果某个数字出现的次数为0,则不要打印它,打印时按照数字的生序排列。

package cn.edu.bupt.array;

import java.util.Arrays;

import java.util.LinkedList;

import java.util.List;

public class RandomNumArray

{

public static void main(String[] args)

{

RandomArray ra = new RandomArray(50);

List list = ra.generateRandomArrayWithNums();

for (NumStruct ns : list)

{

System.out.println(ns.getNum() + "==>" + ns.getTimes());

}

}

}

class RandomArray

{

public RandomArray(int arrayLen)

{

this.randomArray = new int[arrayLen];

this.sortResult = new LinkedList();

}

public List generateRandomArrayWithNums()

{

//生成随机数 for (int i=0; i

{

this.randomArray[i] = (int)(Math.random() * 41 + 10);

}

//对数组进行排序 Arrays.sort(this.randomArray);

for (int i=0; i

{

System.out.print(this.randomArray[i] + " ");

}

System.out.println();

//统计随机数 int counter = 0;

for (int i=0; i

{

counter = 1;

System.out.println(this.randomArray[i]);

for (int j=i+1; j

{

System.out.println(this.randomArray[j]);

counter++;

i++;

}

this.sortResult.add(new NumStruct(this.randomArray[i], counter));

}

return this.sortResult;

}

//private field private int[] randomArray = null;

private List sortResult = null;

}

class NumStruct

{

//constructor public NumStruct(int num, int times)

{

super();

this.num = num;

this.times = times;

}

//getter and setter public int getNum()

{

return num;

}

public int getTimes()

{

return times;

}

//private field private int num;

private int times;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值