/* Balanced tree search.
*
* Implementation history:
* 2013-10-6, Mars Fu, first version.
*/
/* [Balanced Treee Search Algorithm]
* Published by G.M.Adelson-Velsky and E.M.Landis[Soviet Math. Doklady 3(1962),1259~1263].
* Balaned trees also be called AVL trees as the names of authors shown above.
*/
#include "stdafx.h"
#include "balanced_tree_search.h"
struct s_bl_tree_node*
do_balanced_tree_search(struct s_bl_tree_node **root, void *key,
int key_sz, cmp_func cmp, int ins_flag)
{
struct s_bl_tree_node *p, *t, *s, *q, *r;
struct s_bl_tree_node **pp;
int a;
F_S();
if (root == NULL || key == NULL || cmp == NULL) return NULL;
if (key_sz < 0) return NULL;
pp = NULL;
if (*root == NULL) goto INSERT;
s = p = *root;
while (1) {
if (cmp(key, p->key) < 0) {
q = p->left;
pp = &p->left;
}
else if (cmp(key, p->key) > 0) {
q = p->right;
pp = &p->right;
}
else {
goto END;
}
if (q == NULL) break;
if (q->bl_factor != 0) {
t = p;
s = q;
}
p = q;
}
INSERT:
if (!ins_flag) goto INSERT_END;
q = (struct s_bl_tree_node*)malloc(sizeof(struct s_bl_tree_node));
if (q == NULL) return NULL;
q->key = malloc(key_sz);
if (q->key == NULL) {
free(q);
return NULL;
}
memcpy(q->key, key, key_sz);
q->ikey = *(int*)key;
q->left = q->right = NULL;
q->bl_factor = 0;
if (pp == NULL) {
*root = q;
goto INSERT_END;
}
*pp = q;
/* adjust balance factors.
*/
a = (cmp(key, s->key) < 0 ? -1 : 1);
r = p = (a == -1 ? s->left : s->right);
while (p != q) {
if (cmp(key, p->key) < 0) {
p->bl_factor = -1;
p = p->left;
}
else if (cmp(key, p->key) > 0) {
p->bl_factor = 1;
p = p->right;
}
else {
}
}
/* balancing act.
*/
if (s->bl_factor == 0) {
s->bl_factor = a;
}
else if (s->bl_factor == -a) {
s->bl_factor = 0;
}
else if (s->bl_factor == a) {
if (r->bl_factor == a) {
/*
* Os Or
* / \ / \
* O Or => Os Orr
* / \ / \ \
* Orl Orr O Orl Oq
* \
* Oq
*/
p = r;
(a == -1 ? s->left : s->right) = (-a == -1 ? r->left : r->right);
(-a == -1 ? r->left : r->right) = s;
s->bl_factor = r->bl_factor = 0;
}
else if (r->bl_factor == -a) {
/*
* Os Op
* / \ / \
* O Or => Os Or
* / \ / \ / \ / \
* O O Op O O plO Opr O
* / \ \ / \ \ \
* Opl Opr O O O Oq O
* /
* Oq
*/
p = (-a == -1 ? r->left : r->right);
(-a == -1 ? r->left : r->right) = (a == -1 ? p->left : p->right);
(a == -1 ? s->left : s->right) = (-a == -1 ? p->left : p->right);
(a == -1 ? p->left : p->right) = r;
(-a == -1 ? p->left : p->right) = s;
if (p->bl_factor == a) {
s->bl_factor = -a;
r->bl_factor = 0;
}
else if (p->bl_factor == 0) {
s->bl_factor = 0;
r->bl_factor = 0;
}
else if (p->bl_factor == -a) {
s->bl_factor = 0;
r->bl_factor = a;
}
else {
}
p->bl_factor = 0;
}
else {
}
s == t->right ? (t->right = p) : (t->left = p);
}
else {
}
INSERT_END:
return (ins_flag ? q : NULL);
END:
F_E();
return p;
}
#ifdef BALANCED_TREE_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);
}
int
main(int argc, char* argv[])
{
int i;
int cnt;
int int_items[16] = { 503, 87, 512, 61, 908, 170, 897, 275,
653, 426, 154, 509, 612, 677, 765, 703
};
int key;
struct s_bl_tree_node *root;
struct s_bl_tree_node *ret;
debug("[Debug balanced tree 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");
root = NULL;
for (i = 0; i < cnt; ++i) {
debug("\r\n----\r\n");
key = int_items[i];
debug("insert key %d into tree... \r\n", key);
ret = do_balanced_tree_search(&root, &key, sizeof(key), int_cmp, 1);
if (!ret) {
debug("failed. \r\n");
}
else {
debug("done. \r\n");
}
}
debug("\r\n----\r\n");
key = int_items[0];
debug("search key %d... \r\n", key);
ret = do_balanced_tree_search(&root, &key, sizeof(key), int_cmp, 0);
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_balanced_tree_search(&root, &key, sizeof(key), int_cmp, 0);
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_balanced_tree_search(&root, &key, sizeof(key), int_cmp, 0);
if (!ret) debug("not found.\r\n");
debug("\r\n----\r\n");
key = 12345;
debug("search key %d... \r\n", key);
ret = do_balanced_tree_search(&root, &key, sizeof(key), int_cmp, 0);
if (!ret) debug("not found.\r\n");
debug("\r\n");
debug("[Debug balanced tree search]..done. \r\n");
END:
while (1);
return 1;
}
#endif /* BALANCED_TREE_SEARCH_DEBUG */
#ifndef __BALANCED_TREE_SEARCH_H__
#define __BALANCED_TREE_SEARCH_H__
#define BALANCED_TREE_SEARCH_DEBUG
struct s_bl_tree_node {
struct s_bl_tree_node *left;
struct s_bl_tree_node *right;
struct s_bl_tree_node *father;
void *key;
int ikey;
int bl_factor;
};
typedef int(*cmp_func)(void*,void*);
struct s_bl_tree_node* do_balanced_tree_search(struct s_bl_tree_node **root, void *key,
int key_sz, cmp_func cmp, int ins_flag);
#endif /* __BALANCED_TREE_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 7, 2013