线性查找与二分查找法的差异

以数组为对象的两种查找方法对比。


线性查找可以针对任何数组,将数组中的每项依次遍历出来之后,与所要查找项对比。

消耗时间也是不规律的,可能查找项处于数组的第一位,也可能处于数组的最后一位。还有可能数组中完全不存在需要查找的项目。


二分查找法,针对有序数组使用。

因为数组已经有序排列,可以通过将数组从中间分割,将中间项与所需查找项对比;然后再根据对比结果,再次向上或者向下,寻找中间项对比,直至完成查找。

而且,对于查找最开始,可以通过与第一项和最末项的对比,确定查找项是否处于此数组中。



线性查找:

       自定义一个10位的 int[ ] 数组;

public class xianxing {

	private static int[] array;

	public static void main(String[] args) {
		initArray();
		queryArray(56);
	}

	private static void initArray() {
		// 方便和线性查找对比,将数组静态定义
		array = new int[] { 38, 4, 54, 6, 7, 23, 9, 34, 56, 13 };
		// for (int i = 0; i < array.length; i++) {
		// array[i] = (int) (Math.random()*100);
		// System.out.println("array的第"+i+"位的值为"+array[i]);

		// }

	}

	private static void queryArray(int i) {
		// TODO Auto-generated method stub
		for (int j = 0; j < array.length; j++) {
			if (56 == array[j]) {
				System.out.println("共计查找次数" + (j + 1) + "次");

			}
		}
	}

}

运行程序结果: 共计查找次数9次。

我们可以看出面对无序数组,查找消耗的比较次数完全是随机的,但是在多次查找之后,可以得出结论:

平均下来的查找次数为N/2;N为数组的长度。


那么面对有序数组使用二分查找法呢?


二分查找:

我们需要将数组重新排序:使用插入排序为数组排序

private static void initandSortArray() {
		// TODO Auto-generated method stub

		array = new int[] { 38, 4, 54, 6, 7, 23, 9, 34, 56, 13 };
		System.out.println("排序前的数组:{ 38, 4, 54, 6, 7, 23, 9, 34, 56, 13 }");
		SortArray();

		// for (int i = 0; i < array.length; i++) {
		// array[i] = (int) (Math.random()*100);
		// System.out.println("array的第"+i+"位的值为"+array[i]);
		// }
	}

	private static void SortArray() {
		// TODO Auto-generated method stub
		int in, out;

		for (out = 1; out < array.length; out++) { // 被选中暂时移出数组的项
			int temp = array[out];                 // 零时值接受out位置的值
			in = out;                              // 将out前的项整体前移
			while (in > 0 && array[in - 1] >= temp) {
				
				// 将暂时被移除的项与之间的局部已排序的局部列表对比
				
				array[in] = array[in - 1];
				--in;
			}
			array[in] = temp;
		}
		System.out.println("排序后的数组:{");
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i]+",");
		}
	}


输出结果如下:

排序前的数组:{ 38, 4, 54, 6, 7, 23, 9, 34, 56, 13 }
排序后的数组:{
4,6,7,9,13,23,34,38,54,56,

那么看来我们的排序生效了,接下来重写查找方法,使用二分查找法

private static void queryArray(int i) {
		int lowerBound, upperBound;
		lowerBound = 0;// array的起始位置
		upperBound = array.length - 1;// array的结束位置
		int currentLoca;// 目标位置
		if (array[lowerBound] <= i && array[upperBound] >= i
				&& upperBound >= upperBound)// 已知从小到大的排序可以加上此判断
		{	
			int queryCount = 0;//查找计数器
			while (true) {
				queryCount++;
				currentLoca = (lowerBound + upperBound) / 2;
				if (array[currentLoca] == i) {
					System.out.println("已经查找到,目标位置:" + currentLoca+";查找次数为"+queryCount);
					return;
				} else {
					if (array[currentLoca] < i) {
						lowerBound = currentLoca + 1;// 查找范围向上移动

					} else {
						upperBound = currentLoca - 1;// 查找范围向下移动
					}
				}

			}
		}
	}

运行结果如下:


已经查找到,目标位置:9;查找次数为4


对比结论:

线性查找:查找次数平均为N/2.

二分查找:查找次数在10位的数组中最大数为4(运气好的好,也许第一次就找到了)。

那么这样看,线性查找只是比二分查找多了一次查找而已,并没有看出二分查找的优势。


如果我们将数组基数放大:

线性查找与二分查找法的差异_第1张图片


那么当数组的基数放大时,线性查找次数将会成正比增长,K=N/2;

而二分查找,我们通过一个公式来表达,K=2(N),对数计算给出了二分查找法最大耗费的次数。

那么N/2与2(N)对比之下,差异性就显现了。


你可能感兴趣的:(JAVA数据结构与算法)