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].. \r\n");



	cnt = sizeof(int_items)/sizeof(int_items[0]);



	debug("src database:\r\n----\r\n");

	for (i = 0; i < cnt; ++i) {

		debug("%d ", int_items[i]);

	}

	debug("\r\n");



	ret = do_quick_sort((void*)int_items, sizeof(int), cnt, 

		                 int_cmp, exchange_int_item, NULL);

	if (!ret) {

		debug("failed. \r\n");

		goto END;

	}



	debug("src database sorted:\r\n----\r\n");

	for (i = 0; i < cnt; ++i) {

		debug("%d ", int_items[i]);

	}

	debug("\r\n");



	debug("\r\n----\r\n");

	key = int_items[0];

	debug("search key %d... \r\n", key);

    ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");



	debug("\r\n----\r\n");

	key = int_items[cnt-1];

	debug("search key %d... \r\n", key);

    ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");



	debug("\r\n----\r\n");

	key = int_items[cnt/2];

	debug("search key %d... \r\n", key);

    ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");



	debug("\r\n----\r\n");

	key = 12345;

	debug("search key %d... \r\n", key);

    ret = do_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");

    ret = do_uniform_binary_search_2(&key, int_items, sizeof(int), cnt, int_cmp);

	if (!ret) debug("not found.\r\n");



	debug("\r\n");



	debug("[Debug binary search]..done. \r\n");

    

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]..\r\n", __FUNCTION__)

#define F_E() debug("[%s]..done. \r\n", __FUNCTION__)


Foundation: Binary Search

Foundation: Binary Search

Enjoy~

Mars微笑

October 5, 2013

 

你可能感兴趣的:(Binary search)