Foundation: Binary Search

时间:2023-03-09 15:27:04
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~

MarsFoundation: Binary Search

October 5, 2013