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

  • 相关阅读:
    IE安全级别没法定制
    将应用部署到Websphere的context root根/
    SqlServer插入慢的问题解决
    SqlServer中用@@IDENTITY取最新ID不准的问题
    分享我的戒烟经验
    Telnet发邮件过程
    .net垃圾回收和CLR 4.0对垃圾回收所做的改进之三
    Please pay more attention to the character set of your database
    翻旧贴: 什么是对象?
    C# Code in ASPX Page
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3353237.html
Copyright © 2011-2022 走看看