Foundation: Balanced Tree Search

/* 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值