Foundation: Binary Search

来源:互联网 发布:手办 淘宝 推荐 编辑:程序博客网 时间:2024/05/29 18:45
/* 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_DEBUGint 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 voidexchange_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;}intmain(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_DEBUGtypedef 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__)


Enjoy~

Mars微笑

October 5, 2013

原创粉丝点击