//load words into an avl tree TREE_NODE * index_file(char *file_name){ FILE *file; file = fopen(file_name,"r"); if(!file){ printf("arquivo de entrada invalido\n"); return NULL; } wchar_t line [ 10000 ]; wchar_t *token; wchar_t *state; const wchar_t delimiters[] = L" \n,.;'\"?-|:*&!@$%{}()[]<>\\";//only consider letters int current_line = 1; TREE_NODE *tree = NULL; W_TOKEN *w_token = NULL; while ( fgetws ( line, sizeof(line), file ) ){//read line by line for (token = wcstok(line, delimiters, &state); token != NULL; token = wcstok(NULL, delimiters, &state)) { if(token) w_token = create_word(token); insert_avl(&tree, (void *)w_token, lex_order, current_line); } current_line++; } fclose ( file ); return tree; }
int main(int argc, char *argv[]) { int i; int a[10] = {3, 2, 1, 4, 5, 6, 7, 20, 16, 10}; struct avl *tree = NULL; int taller = 0; for (i = 0; i < 10; ++i) insert_avl(&tree, a[i], &taller); in_order_traverse(tree); printf("\nAfter insert 12:\n"); insert_avl(&tree, 12, &taller); in_order_traverse(tree); printf("\n"); return 0; }
void insert_avl(TREE_NODE** t, void *data, comparator comparator, int line ){ int *line_number = malloc(sizeof(int)); *line_number = line; if(!*t){//insert new node in tree *t = (TREE_NODE*)malloc(sizeof(TREE_NODE)); (*t)->data = data; append(&( ( (W_TOKEN *)( (*t)->data ) )->list ), line_number); (*t)->height = 0; (*t)->left = (*t)->right = NULL; } else if (comparator(data , (*t)->data) < 0 ){ insert_avl( &((*t)->left), data, comparator, line ); if( height( (*t)->left ) - height( (*t)->right ) == 2 ){ if (comparator(data , (*t)->left->data) < 0 ){ *t = rotate_left( *t ); } else if (comparator(data , (*t)->left->data) > 0 ){ *t = double_left_rotate( *t ); } } } else if (comparator(data , (*t)->data) > 0 ){ insert_avl( &( (*t)->right ), data, comparator, line ); if( height( (*t)->right ) - height( (*t)->left ) == 2 ){ if (comparator(data , (*t)->right->data) > 0 ){ *t = rotate_right( *t ); } else if (comparator(data , (*t)->right->data) < 0 ){ *t = double_right_rotate( *t ); } } } else{//word already in tree, add line number to list append(&( ( (W_TOKEN *)( (*t)->data ) )->list ), line_number); } (*t)->height = max( height( (*t)->left ), height( (*t)->right ) ) + 1; }
/* Read an opening book file and store its positions in an AVL tree. Returns 0 if successfull. */ int book_to_tree(const char *filename, AvlNode **tree) { int i; U16 games; U16 wins; int npos; U64 key; FILE *fp; ASSERT(1, filename != NULL); ASSERT(1, tree != NULL); if ((fp = fopen(filename, "rb")) == NULL) { my_perror("Can't open file %s", filename); return -1; } clear_avl(*tree); *tree = NULL; npos = get_pos_count(fp); for (i = 0; i < npos; i++) { if (fread(&key, sizeof(U64), 1, fp) != 1 || fread(&games, sizeof(U16), 1, fp) != 1 || fread(&wins, sizeof(U16), 1, fp) != 1) { my_close(fp, filename); my_perror("Can't read file %s", filename); return -1; } /* Make sure the data is in the right endian format. */ key = fix_endian_u64(key); games = fix_endian_u16(games); wins = fix_endian_u16(wins); *tree = (AvlNode*)insert_avl(*tree, key, games, wins); } my_close(fp, filename); return 0; }
/* Store a position in an AVL tree. Returns true if the position is new. */ bool save_book_pos(U64 key, int points, AvlNode **tree) { U16 wins = 0; AvlNode *node; ASSERT(1, tree != NULL); ASSERT(1, points == 0 || points == 2); book_modified = true; if (points == 2) wins = 1; if ((node = (AvlNode*)find_avl(*tree, key)) != NULL) { if (node->games < UINT16_MAX) { (node->games)++; node->wins += wins; } return false; } *tree = (AvlNode*)insert_avl(*tree, key, 1, wins); return true; }
/* * 插入结点到AVL树 * * 结点已存在,返回0;出错,返回-1,成功返回1 */ int insert_avl(struct avl **tree, int item, int *taller) { int ret = 0; if (*tree == NULL) { /* 树为空,插入为根结点 */ *tree = (struct avl *) malloc(sizeof(struct avl)); if (*tree == NULL) return -1; (*tree)->data = item; (*tree)->lchild = (*tree)->rchild = NULL; (*tree)->bf = EH; *taller = 1; /* 树长高了 */ } else { /* 结点已经存在 */ if (item == (*tree)->data) { *taller = 0; return 0; } /* 结点小于根结点,往左子树查找,递归 */ if (item < (*tree)->data) { ret = insert_avl(&(*tree)->lchild, item, taller); if (ret != 1) /* 未插入 */ return ret; /* 新插入结点到左子树,且左子树长高了 */ if (*taller == 1) { /* 检查树的平衡度 */ switch ((*tree)->bf) { case LH: /* 插入结点后,左子树比右子树高,作左平衡处理 */ left_balance(tree); *taller = 0; break; case EH: /* 原本左右子树等高,插入新结点后,根增高 */ (*tree)->bf = LH; *taller = 1; break; case RH: /* 原本右子树比左子树高,插入后等高 */ (*tree)->bf = EH; *taller = 0; break; } } /* 结点大于根结点,往右子树查找,递归 */ } else if (item > (*tree)->data) { ret = insert_avl(&(*tree)->rchild, item, taller); if (ret != 1) /* 未插入 */ return ret; /* 新插入结点到右子树,且右子树长高了 */ if (*taller == 1) { /* 检查树的平衡度 */ switch ((*tree)->bf) { case LH: /* 原本左子树比右子树高,插入后等高 */ (*tree)->bf = EH; *taller = 0; break; case EH: /* 原本左右子树等高,插入结点后,树增高 */ (*tree)->bf = RH; *taller = 1; break; case RH: /* 插入后右子树比左子树高,作右平衡处理 */ right_balance(tree); *taller = 0; break; } } } } return 1; }