/** Função recursiva de inserção na árvore AVL. */ int insertAVL_TreeR(struct AVL_TreeNode **node, void *elem, int *h) { if (!*node) {//se o nó não existir, é criado um novo no AVL_TreeNode *novo = (AVL_TreeNode*) malloc(sizeof (AVL_TreeNode)); novo->elem = elem; novo->fb = 0; novo->left = NULL; novo->right = NULL; *node = novo; *h = 1; //haverá mudança na altura return 1; } else { if (*(int*) (*node)->elem == *(int*) elem) { *h = 0; return 0; } if (*(int*) elem < *(int*) (*node)->elem) { insertAVL_TreeR(&((*node)->left), elem, h); if (*h == 1) { //se h = 1 então houve mudança na altura da arvore então terã de recalcular o FB e talvez rebalancear. //Se rebalancear então não haverá mais mudança na altura. if ((*node)->fb == 0) { //Se fb era 0 então estava balanceada, (*node)->fb--; //inserindo alguém a esquerda, diminui o fb de 1 *h = 1; //e haverá mudança na altura } else if ((*node)->fb == 1) {//se o fb era 1 então a direita era mais pesada (*node)->fb--; //Inserindo alguém na esquerda o fb diminuirá de 1 *h = 0; //e não haverá mudança na altura } else if ((*node)->fb == -1) {//se o fb era -1 então a esquerda é mais pesada (*node)->fb = 0; //insserindo alguém na esquerda o fb irá a dois e deverá ser rebalanceada, voltando a 0 RR(&(*node), h); //caso1 } } } else if (*(int*) elem > *(int*) (*node)->elem) { insertAVL_TreeR(&((*node)->right), elem, h); if (*h == 1) { if ((*node)->fb == 1) {//Se fb era 1 então a direita ja tinha alguem, faz uma rotação para esquerda e a altura não muda LR(&(*node), h); *h = 0; } else if ((*node)->fb == 0) { (*node)->fb++; *h = 1; } else if ((*node)->fb == -1) { //Se fb era -1 então a esquerda era maior, como foi inserido na direita, a altura não muda. (*node)->fb++; *h = 0; } } } } }
int insertAVL_Tree(struct AVL_Tree *tree, void *elem) { struct AVL_TreeNode **node = &(tree->root); //Estou ignorando o h que será enviado, a altura do nó será calculada por outra função int retorno = insertAVL_TreeR(node, elem, NULL); balancearArvore(tree); return retorno; }
/** Insere um elemento na árvore binária. Retorna 1, caso tenha inserido o elemento com sucesso, e 0 caso contrário. */ int insertAVL_Tree(struct AVL_Tree *tree, void *elem) { if (!tree)return 0; int *h = (int*) malloc(sizeof (int)); *h = 1; AVL_TreeNode **ptp = &(tree->root); int x = insertAVL_TreeR(ptp, elem, h); return x; }
int insertAVL_TreeR(struct AVL_TreeNode **node, void *elem, int *h) { if ((*node) == NULL) { //Condição de parada struct AVL_TreeNode *novoNo = NULL; novoNo = criarNo(); novoNo->elem = elem; (*node) = novoNo; return 1; } else { if (*(int*)elem < *(int*)(*node)->elem) { //Compara o elemento do o nó corrente, se for menor, executa recursivamente no nó da esquerda struct AVL_TreeNode **noAux = &((*node)->left); //Estou ignorando o h que será enviado, a altura do nó será calculada por outra função return insertAVL_TreeR(noAux, elem, NULL); } else if (*(int*)elem > *(int*)(*node)->elem) { //Compara o elemento do o nó corrente, se for maior, executa recursivamente no nó da direita struct AVL_TreeNode **noAux = &((*node)->right); //Estou ignorando o h que será enviado, a altura do nó será calculada por outra função return insertAVL_TreeR(noAux, elem, NULL); } } return 0; }