pi tp 11
Tópicos: Árvores Binárias (ABin) e Árvores Binárias de Procura (BST/ABB).
Estruturas Base (Para Contexto)
typedef struct lligada {
int valor;
struct lligada *prox;
} *LInt;
typedef struct nodo {
int valor;
struct nodo *esq, *dir;
} *ABin;1. Operações Básicas em Árvores Binárias
Contar Folhas (nFolhas)
Uma folha é um nó que não tem filhos (nem esquerda, nem direita).
int nFolhas(ABin a) {
if (a == NULL) return 0;
// Se não tem filhos, é uma folha
if (a->esq == NULL && a->dir == NULL) return 1;
// Senão, soma as folhas da esquerda com as da direita
return nFolhas(a->esq) + nFolhas(a->dir);
}Imprimir Travessia Inorder (inorder)
Visita a árvore na ordem: Esquerda → Raiz → Direita. (Numa árvore de procura, isto imprime os valores por ordem crescente).
void inorder(ABin a){
if(a != NULL){
inorder(a->esq);
printf("%d", a->valor);
inorder(a->dir);
}
}void imprimeNivel(ABin a, int n){
if (a != NULL){
if(n == 0) printf("%d", a->valor);
else{
imrprimeNivel(a->esq, n-1);
imprimeNivel(a->dir, n-1);
}
}
}2. Operações por Nível (Profundidade)
Imprimir os Valores de um Nível Específico (imprimeNivel)
void imprimeNivel(ABin a, int n){
if (a != NULL){
if(n == 0) printf("%d", a->valor);
else {
// desce na árvore e diminui a distância (n) para o alvo
imrprimeNivel(a->esq, n-1);
imprimeNivel(a->dir, n-1);
}
}
}Criar Lista Ligada com Valores de um Nível (nivelL)
Requer uma função auxiliar append para juntar as listas geradas pela subárvore esquerda e direita.
// Função aux: junta a lista 'b' ao final da lista 'a'
LInt append( LInt a, LInt b){
LInt r = a;
if(a == NULL) r = b;
while(a->prox != NULL) a = a->prox;
a->prox = b;
return r
}
// função principal
LInt nivelL(ABin a, int n){
LInt r = NULL, e, d;
if(a != NULL){
if(n == 0){
r = malloc(sizeof(struct lligada));
r->valor = a->valor;
r->prox = NULL;
}
} else {
e = nivelL(a->esq, n-1);
d = nivelL(a->dir, n-1);
r = append(e, d)
}
return r;
}3. Árvores Binárias de Procura (BST)
Numa Ár-do à esquerda é menor, e tudo à direita é maior.
Procurar um Elemento (procura e procura2)
// versão recursiva
ABin procura( LInt a, int x){
ABin r = NULL;
if(a != NULL){
if(x == a->valor) r = a;
else if(x < a->valor) r = procura(a->esq, x);
else r = procura(a->dir, x);
}
return r;
}// versão iterativa
ABin procura2(ABin a, int x){
while(a != NULL && a->valor != x){
if(x < a->valor) a = a->esq;
else a = a->dir;
}
return a;
}Encontrar o Nível de um Elemento (nivel)
Retorna -1 se o elemento não existir. A raiz está no nível 0.
int nivel(ABin a, int x){
// -1 se x não existir
int nivel = 0;
while(a != NULL && a->valor != x){
if(x < a->valor) a = a->esq;
else a = a->dir;
nivel++
}
return (a == NULL)? -1 : nivel;
}Imprimir Elementos Menores ou Iguais a X (imprimeAte)
Usa a propriedade da árvore de procura para não visitar ramos desnecessários.
void imprimeAte(Abin a, int x){
if(a != NULL){
if(x > a->valor){
// tudo à esquerda é garantidamente menor, imprimimos logo
inorder(a->esq);
printf("%d", a->valor); // imprimimos o valor atual
imprimeAte(a->dir, x); // procuramos à direita por mais valores que ainda sejam <= x
}
else imprimeAte(a->esq, x) // se o valor é maior que x, ignoramos a direita e vamos só pela esquerda
}
}Main
arvore:
10
/ \
5 15
/ \ \
2 7 20#include <stdio.h>
#include <stdlib.h>
// ==========================================
// 1. ESTRUTURAS
// ==========================================
typedef struct lligada {
int valor;
struct lligada *prox;
} *LInt;
typedef struct nodo {
int valor;
struct nodo *esq, *dir;
} *ABin;
// ==========================================
// 2. FUNÇÃO EXTRA PARA AJUDAR NO MAIN
// ==========================================
ABin novoNodo(int x, ABin e, ABin d) {
ABin n = malloc(sizeof(struct nodo));
n->valor = x;
n->esq = e;
n->dir = d;
return n;
}
// ==========================================
// 3. AS TUAS FUNÇÕES DO TP 11
// ==========================================
int nFolhas(ABin a) {
if (a == NULL) return 0;
if (a->esq == NULL && a->dir == NULL) return 1;
return nFolhas(a->esq) + nFolhas(a->dir);
}
void imprimeNivel(ABin a, int n) {
if (a != NULL) {
if (n == 0) printf("%d ", a->valor);
else {
imprimeNivel(a->esq, n - 1);
imprimeNivel(a->dir, n - 1);
}
}
}
LInt append(LInt a, LInt b) {
if (a == NULL) return b;
LInt r = a;
while (a->prox != NULL) a = a->prox;
a->prox = b;
return r;
}
LInt nivelL(ABin a, int n) {
LInt r = NULL, e, d;
if (a != NULL) {
if (n == 0) {
r = malloc(sizeof(struct lligada));
r->valor = a->valor;
r->prox = NULL;
} else {
e = nivelL(a->esq, n - 1);
d = nivelL(a->dir, n - 1);
r = append(e, d);
}
}
return r;
}
int nivel(ABin a, int x) {
int nivel = 0;
while (a != NULL && a->valor != x) {
if (x < a->valor) a = a->esq;
else a = a->dir;
nivel++;
}
return (a == NULL) ? -1 : nivel;
}
void inorder(ABin a) {
if (a != NULL) {
inorder(a->esq);
printf("%d ", a->valor);
inorder(a->dir);
}
}
void imprimeAte(ABin a, int x) {
if (a != NULL) {
if (a->valor <= x) {
inorder(a->esq);
printf("%d ", a->valor);
imprimeAte(a->dir, x);
} else {
imprimeAte(a->esq, x);
}
}
}
// ==========================================
// 4. MAIN PARA O PYTHON TUTOR
// ==========================================
int main() {
printf("=== CONSTRUINDO A ARVORE ===\n");
// Montamos a árvore de baixo para cima usando a função auxiliar
// Árvore: Raiz 10, Esquerda 5 (com filhos 2 e 7), Direita 15 (com filho 20)
ABin raiz = novoNodo(10,
novoNodo(5,
novoNodo(2, NULL, NULL),
novoNodo(7, NULL, NULL)),
novoNodo(15,
NULL,
novoNodo(20, NULL, NULL)));
printf("\n=== TESTANDO FUNCOES ===\n");
// Teste 1: Contar folhas (Devem ser o 2, 7 e 20 -> Total 3)
int folhas = nFolhas(raiz);
printf("Numero de folhas: %d\n", folhas);
// Teste 2: Procurar o nivel do numero 7 (A raiz 10 e nivel 0, o 5 e nivel 1, o 7 e nivel 2)
int n = nivel(raiz, 7);
printf("O numero 7 esta no nivel: %d\n", n);
// Teste 3: Imprimir todos os elementos da arvore em ordem crescente
printf("Inorder (crescente): ");
inorder(raiz);
printf("\n");
// Teste 4: Imprimir valores ate um limite (Ex: todos os <= 8)
printf("Imprime ate o 8: ");
imprimeAte(raiz, 8); // Deve imprimir 2, 5 e 7
printf("\n");
// Teste 5: Criar uma lista ligada com os elementos do nivel 2 (o 2, o 7 e o 20)
LInt listaNivel2 = nivelL(raiz, 2);
// FIM! Acompanha os ponteiros da lista no Python Tutor
return 0;
}