/* As we all know that, binary searching is a efficiency searching method, * but, there is a precondition that the elements must be sorted in * either ascending or descending. So when the data are input in mess * order, binary searching can hardly be used. The dynamic searching * tree has a very important character, a binary tree is created in * the progress of searching, and the elements are in ascending sequence * when the tree is traversed in in-order sequence. This shows us the * possibility to achieve the most favorite searching efficiency of * binary-searching even the elements are input in mess order. * Unfortunately, reality not always satisfies us. When the dynamic * searching tree is not balanced, the searching efficiency is not * enjoyable. So, in the progress of dynamic searching, each node * of the tree element must be made balanced. * * The following codes show how to creat a balanced binary searching tree(BBST), * which is also called AVL tree. * by:double; version:0.1; date:2009-08-23 */ #include "/usr/c/head.h" #define LH +1 #define EH 0 #define RH -1 #define MAX 200 #define INT_MAX ((int)(~0U >> 1)) #define EQ(a, b) ((a) == (b)) #define LT(a, b) ((a) < (b)) #define LQ(a, b) ((a) <= (b)) typedef int boolean; typedef int key_type; typedef struct dst_tree_node { key_type data; int bf; struct dst_tree_node * lchild, * rchild; }dst_tree_node, * dst_tree; status right_rotate(dst_tree *p) { dst_tree lc; lc = (*p)->lchild; (*p)->lchild = lc->rchild; lc->rchild = *p; *p = lc; return OK; } status left_rotate(dst_tree *p) { dst_tree rc; rc = (*p)->rchild; (*p)->rchild = rc->lchild; rc->lchild = *p; *p = rc; return OK; } status left_balance(dst_tree *T) { dst_tree lc, rc; lc = (*T)->lchild; switch (lc->bf) { case LH: (*T)->bf = lc->bf = EH; right_rotate(T); break; case RH: rc = lc->rchild; switch(rc->bf) { case LH: (*T)->bf = RH; lc->bf = EH; break; case EH: (*T)->bf = lc->bf = EH; break; case RH: (*T)->bf = EH; lc->bf = LH; break; } rc->bf = EH; left_rotate(&(*T)->lchild); right_rotate(T); } return OK; /* Remember a formula: parent-left left right; lchild-left right left. * The formula is for (*T)->bf and lc->bf. "parent" means *T, "lchild" * means lc ((*T)->lchild). The first left means the "parent" is left-high * The second left means the lc->rchild is left-high. The right means * in case of parent is left high and the right child of lc (lchild of parent) * is also left high, after being rotated the new balance factor of the * parent is right high. */ } status right_balance(dst_tree *T) { dst_tree lc, rc; rc = (*T)->rchild; switch(rc->bf) { case RH: (*T)->bf = rc->bf = EH; left_rotate(T); break; case LH: lc = rc->lchild; switch(lc->bf) { case LH: (*T)->bf = EH; rc->bf = RH; break; case EH: (*T)->bf = rc->bf = EH; break; case RH: (*T)->bf = LH; rc->bf = EH; break; } lc->bf = EH; right_rotate(&(*T)->rchild); left_rotate(T); } return OK; /* Remember a formula: parent-right right left, rchild-right left right.*/ } status insert_avl(dst_tree *T, key_type e, boolean *taller) { if (!(*T)) { *T = (dst_tree)malloc(sizeof(dst_tree_node)); if (!(*T)) exit(OVERFLOW); (*T)->data = e; (*T)->lchild = (*T)->rchild = NULL; (*T)->bf = EH; *taller = TRUE; } else { if (EQ(e, (*T)->data)) { *taller = FALSE; return 0; } else { if (LT(e, (*T)->data)) { if (!insert_avl(&(*T)->lchild, e, taller)) return 0; else if (*taller){ switch((*T)->bf) { case LH: left_balance(T); *taller = FALSE; break; case EH: (*T)->bf = LH; *taller = TRUE; break; case RH: (*T)->bf = EH; *taller = FALSE; break; } } } else { if (!insert_avl(&(*T)->rchild, e, taller)) return 0; else if (*taller) { switch((*T)->bf) { case LH: (*T)->bf = EH; *taller = FALSE; break; case EH: (*T)->bf = RH; *taller = TRUE; break; case RH: right_balance(T); *taller = FALSE; break; } } } } } return 1; } status visit(key_type e) { printf("%d/t", e); return OK; } status in_order_traverse(dst_tree T) { if (T) { in_order_traverse(T->lchild); visit(T->data); in_order_traverse(T->rchild); } return OK; } status first_order_traverse(dst_tree T) { if (T) { visit(T->data); first_order_traverse(T->lchild); first_order_traverse(T->rchild); } return OK; } int main(void) { dst_tree T = NULL; key_type e; boolean taller; int i, n, temp; printf("How many:"); SCAN_INT(n, temp); for (i = 1; i <= n; ++i) { printf("No.%d:", i); SCAN_INT(e, temp); insert_avl(&T, e, &taller); } printf("In order traverse is:/n"); in_order_traverse(T); printf("/n"); printf("First order traverse is:/n"); first_order_traverse(T); printf("/n"); return 0; }