1. 程式人生 > >算法系列(二)查詢演算法--基本查詢和二分查詢

算法系列(二)查詢演算法--基本查詢和二分查詢

算法系列(一)基本概念 一文中,簡單介紹了演算法基本概念,演算法複雜度評估,常用演算法證明方式。這篇文章介紹一下查詢演算法,主要是二分查詢演算法。

從n個元素中A0,A1....An-1中,找到要找到的元素x,最簡單的方法是遍歷n個元素,找到元素x則返回x的位置,這種演算法的時間複雜度為O(n)。

如果這n個元素是有序的,我們不需要從頭到尾遍歷一遍就可以找到要查詢的元素,可以使用二分法。二分查詢的時間複雜度是O(lgn)

二分查詢的前提是元素有序(一般是升序),基本思想是拿中間元素A[m]與要查詢的元素x進行比較,如果相等,則已經找到,如果A[m]比x大,那麼要找的元素一定在A[m]前邊,如果A[m]比x小,那麼要找的元素一定在A[m]後邊。沒進行一次查詢,陣列規模減半。反覆將子陣列規模減半,直到發現要查詢的元素,或者當前子陣列為空。

例如,在[1,2,3,4,5]中查詢2

第一次找到的數字下標是(0+4)/2=2,找到的數字是3,3<2,要找的數字位置位於[0,2)之間

第二次找到的數字下標是(0+1)/2=0,找到的數字是1,1<2,要找的數字位於(0,1]之間

第三次找到的數字下標是(1+1)/2=1,找到數字2,返回找到的位置1.

如果這個時候找到的數字不是1,那麼說明陣列中沒有要找的數字。

需要注意的點就是區間位置,既然A[m]不等於x,下一次肯定不是從m這個位置開始找的,而是以m+1作為下一個起始位置,或者m-1作為下一個開始位置

二分查詢有兩種實現方式,一種是遞迴實現,一種是非遞迴實現

直接上程式碼

package com.algorithm.tree;

import java.util.Arrays;

/**
 * 二分查詢
 * 
 * @author chao
 *
 */
public class BinarySearchTree {
	/**
	 * 非遞迴二分查詢
	 * 
	 * @param num
	 * @param number
	 * @return
	 */
	public static int binarySearch(int num[], int number) {
		if (num == null || num.length == 0) {
			return -1;
		}
		int start, end, mid;
		start = 0;
		end = num.length - 1;
		while (start <= end) {
			mid = (start + end) / 2;
			if (num[mid] == number)
				return mid;
			else if (num[mid] > number) {
				end = mid - 1;
			} else {
				start = mid + 1;
			}
		}
		return -1;
	}

	/**
	 * 遞迴查詢
	 * 
	 * @param num
	 * @param number
	 * @return
	 */
	public static int RecursivebinarySearch(int num[], int start, int end, int key) {
		int mid = (start + end) / 2;
		if (num == null || num.length == 0 || key < num[start] || key > num[end]) {
			return -1;
		} else if (num[mid] > key) {
			return RecursivebinarySearch(num, start, mid - 1, key);
		} else if (num[mid] < key) {
			return RecursivebinarySearch(num, mid + 1, end, key);
		} else {
			return mid;
		}

	}

	public static void main(String[] args) {
		int num[] = { 3, 5, 7, 9, 10 };
		Arrays.sort(num);
		System.out.println(binarySearch(num, 7));
		System.out.println(binarySearch(num, 8));
		System.out.println(RecursivebinarySearch(num, 0, num.length - 1, 7));
		System.out.println(RecursivebinarySearch(num, 0, num.length - 1, 8));
	}
}

這裡的排序直接使用了java的api,後邊再詳細介紹排序演算法

演算法實現程式碼github地址為https://github.com/robertjc/simplealgorithm

後續會不斷補充,有些地方寫的可能有問題,請多指教。

歡迎掃描二維碼,關注我的公眾賬號