zoukankan      html  css  js  c++  java
  • Foundation: Binary Search

    /* Binary search. 
     *
     * Implementation history: 
     * 2013-10-5, Mars Fu, first version. 
     */  
      
    /* [Binary Search Algorithm]
     * Published by John Mauchly(1946) and D.H.Lehmer(1960).
     *
     * [Uniform Binary Search Algorithm]
     * Published by D.E.Knuth(1963) and A.K.Chandra(1971).
     */
    
    
    #include "stdafx.h"
    #include "binary_search.h"
    #include "quicksort.h"
    
    
    int 
    do_binary_search(void *key, void *src, int src_sz, int n, cmp_func cmp)
    {
    	int li,ri,i;
    	char *p;
    
        F_S();
    
    	if (key == NULL || src == NULL || cmp == NULL) return 0;
    	if (src_sz <= 0 || n <= 0) return 0;
    
    	li = 1; 
    	ri = n;
    	while (li <= ri) { 
    
    		i = ((li + ri) >> 1);
    
    		p = (char*)src + (i-1) * src_sz;
    		if (cmp(key, p) < 0) {
    			ri = i - 1;
    		}
    		else if (cmp(key, p) > 0) {
    			li = i + 1;
    		}
    		else {
    			goto END;	
    		}
    	}
    
    	return 0;
    
    END:
    	F_E();
    	return i;
    }
    
    
    int 
    do_uniform_binary_search(void *key, void *src, int src_sz, int n, cmp_func cmp)
    {
    	int i,m;
    	char *p;
    
        F_S();
    
    	if (key == NULL || src == NULL || cmp == NULL) return 0;
    	if (src_sz <= 0 || n <= 0) return 0;
    
    	i = (n + 1) / 2;
    	m = n / 2;
    	while (1) {
    
    		p = (char*)src + (i-1) * src_sz;
    		if (cmp(key, p) < 0) {
    			if (m == 0) return 0;
    			i -= ((m + 1) / 2);
    		}
    		else if (cmp(key, p) > 0) {
    			if (m == 0) return 0;
    			i += ((m + 1) / 2);
    		}
    		else {
    			goto END;	
    		}
    
    		m = m / 2;
    	}
    
    	return 0;
    END:
    	F_E();
    	return i;
    }
    
    int 
    do_uniform_binary_search_2(void *key, void *src, int src_sz, int n, cmp_func cmp)
    {
    	int i,j,k,h,m;
    	char *p;
    	int n2;
    
        F_S();
    
    	if (key == NULL || src == NULL || cmp == NULL) return 0;
    	if (src_sz <= 0 || n <= 0) return 0;
    
    	/* formula:
    	 * h(j) = (n + 2^(j-1)) / (2^j), where 1 <= j <= (int)lg(n) + 2.
    	 */
    	n2 = 2;
    	m = (int)(log((double)n) / log((double)n2)) + 2;
    
    	for (i = (n + 1) / 2, j = 1, k = 2; j < m; ++j, k <<= 1) {
    
    		h = (n + k) / (k << 1);
    
    		p = (char*)src + (i-1) * src_sz;
    		if (cmp(key, p) < 0) {
    			if (h == 0) return 0;
    			i -= h;
    		}
    		else if (cmp(key, p) > 0) {
    			if (h == 0) return 0;
    			i += h;
    		}
    		else {
    			goto END;	
    		}
    	}
    
    	return 0;
    END:
    	F_E();
    	return i;
    }
    
    #ifdef BINARY_SEARCH_DEBUG
    
    int 
    int_cmp(void* lv, void* rv)
    {
    	int tmp_lv, tmp_rv;
    	
    	tmp_lv = *(int*)lv;
    	tmp_rv = *(int*)rv;
    
    	return (tmp_lv - tmp_rv);
    }
    
    static void
    exchange_int_item(void* lv, void* rv)
    {
    	int tmp_lv, tmp_rv;
    	
    	tmp_lv = *(int*)lv;
    	tmp_rv = *(int*)rv;
    
    	*(int*)lv = *(int*)rv;
    	*(int*)rv = tmp_lv;
    }
    
    int
    main(int argc, char* argv[])
    {
    	int i;
    	int cnt;
    	int ret;
    	int int_items[16] = { 503, 87, 512, 61, 908, 170, 897, 275, 
    		                  653, 426, 154, 509, 612, 677, 765, 703
    	                    };
        int key;
    
    	debug("[Debug binary search].. 
    ");
    
    	cnt = sizeof(int_items)/sizeof(int_items[0]);
    
    	debug("src database:
    ----
    ");
    	for (i = 0; i < cnt; ++i) {
    		debug("%d ", int_items[i]);
    	}
    	debug("
    ");
    
    	ret = do_quick_sort((void*)int_items, sizeof(int), cnt, 
    		                 int_cmp, exchange_int_item, NULL);
    	if (!ret) {
    		debug("failed. 
    ");
    		goto END;
    	}
    
    	debug("src database sorted:
    ----
    ");
    	for (i = 0; i < cnt; ++i) {
    		debug("%d ", int_items[i]);
    	}
    	debug("
    ");
    
    	debug("
    ----
    ");
    	key = int_items[0];
    	debug("search key %d... 
    ", key);
        ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
    
    	debug("
    ----
    ");
    	key = int_items[cnt-1];
    	debug("search key %d... 
    ", key);
        ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
    
    	debug("
    ----
    ");
    	key = int_items[cnt/2];
    	debug("search key %d... 
    ", key);
        ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
    
    	debug("
    ----
    ");
    	key = 12345;
    	debug("search key %d... 
    ", key);
        ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
        ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);
    	if (!ret) debug("not found.
    ");
    
    	debug("
    ");
    
    	debug("[Debug binary search]..done. 
    ");
        
    END:
    	while (1);
    	return 1;
    }
    
    #endif /* BINARY_SEARCH_DEBUG */
    #ifndef __BINARY_SEARCH_H__
    #define __BINARY_SEARCH_H__
    
    #define BINARY_SEARCH_DEBUG
    
    typedef int(*cmp_func)(void*,void*);
    
    int do_binary_search(void *key, void *src, int src_sz, int n, cmp_func cmp);
    int do_uniform_binary_search(void *key, void *src, int src_sz, int n, cmp_func cmp);
    int do_uniform_binary_search_2(void *key, void *src, int src_sz, int n, cmp_func cmp);
    
    #endif /* __BINARY_SEARCH_H__ */
    #pragma once
    
    #include <windows.h>
    #ifdef _WIN32
    #define msleep(x)  Sleep(x)
    #endif
    
    #include <stdio.h>
    #include <tchar.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    #include <math.h>
    
    #define MY_DEBUG
    #ifdef MY_DEBUG
    #define debug printf
    #else
    #define debug(x,argc, __VA_ARGS__)	;
    #endif /* MY_DEBUG */
    
    #define F_S() debug("[%s]..
    ", __FUNCTION__)
    #define F_E() debug("[%s]..done. 
    ", __FUNCTION__)


    Enjoy~

    Mars微笑

    October 5, 2013

  • 相关阅读:
    383. Ransom Note
    598. Range Addition II
    453. Minimum Moves to Equal Array Elements
    492. Construct the Rectangle
    171. Excel Sheet Column Number
    697. Degree of an Array
    665. Nondecreasing Array
    视频网站使用H265编码能提高视频清晰度吗?
    现阶段的语音视频通话SDK需要解决哪些问题?
    企业远程高清会议平台视频会议系统在手机端使用的必备要求有哪些?
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3353237.html
Copyright © 2011-2022 走看看