Skip to content

Instantly share code, notes, and snippets.

@divanibarbosa
Last active November 4, 2024 23:55
Show Gist options
  • Save divanibarbosa/a8662693e44ab9ee0d0e8c2d74808929 to your computer and use it in GitHub Desktop.
Save divanibarbosa/a8662693e44ab9ee0d0e8c2d74808929 to your computer and use it in GitHub Desktop.
Binary Tree in Python - Arvore Binaria em Python usando classe
# Criado por: profa. Divani Barbosa Gavinier
# Curriculo Lattes: http://lattes.cnpq.br/8503400830635447
# [email protected]
class No:
def __init__(self, key, dir, esq):
self.item = key
self.dir = dir
self.esq = esq
class Tree:
def __init__(self):
self.root = No(None,None,None)
self.root = None
def inserir(self, v):
novo = No(v,None,None) # cria um novo Nó
if self.root == None:
self.root = novo
else: # se nao for a raiz
atual = self.root
while True:
anterior = atual
if v <= atual.item: # ir para esquerda
atual = atual.esq
if atual == None:
anterior.esq = novo
return
# fim da condição ir a esquerda
else: # ir para direita
atual = atual.dir
if atual == None:
anterior.dir = novo
return
# fim da condição ir a direita
def buscar(self, chave):
if self.root == None:
return None # se arvore vazia
atual = self.root # começa a procurar desde raiz
while atual.item != chave: # enquanto nao encontrou
if chave < atual.item:
atual = atual.esq # caminha para esquerda
else:
atual = atual.dir # caminha para direita
if atual == None:
return None # encontrou uma folha -> sai
return atual # terminou o laço while e chegou aqui é pq encontrou item
# O sucessor é o Nó mais a esquerda da subarvore a direita do No que foi passado como parametro do metodo
def nosucessor(self, apaga): # O parametro é a referencia para o No que deseja-se apagar
paidosucessor = apaga
sucessor = apaga
atual = apaga.dir # vai para a subarvore a direita
while atual != None: # enquanto nao chegar no Nó mais a esquerda
paidosucessor = sucessor
sucessor = atual
atual = atual.esq # caminha para a esquerda
# *********************************************************************************
# quando sair do while "sucessor" será o Nó mais a esquerda da subarvore a direita
# "paidosucessor" será o o pai de sucessor e "apaga" o Nó que deverá ser eliminado
# *********************************************************************************
if sucessor != apaga.dir: # se sucessor nao é o filho a direita do Nó que deverá ser eliminado
paidosucessor.esq = sucessor.dir # pai herda os filhos do sucessor que sempre serão a direita
# lembrando que o sucessor nunca poderá ter filhos a esquerda, pois, ele sempre será o
# Nó mais a esquerda da subarvore a direita do Nó apaga.
# lembrando também que sucessor sempre será o filho a esquerda do pai
sucessor.dir = apaga.dir # guardando a referencia a direita do sucessor para
# quando ele assumir a posição correta na arvore
return sucessor
def remover(self, v):
if self.root == None:
return False # se arvore vazia
atual = self.root
pai = self.root
filho_esq = True
# ****** Buscando o valor **********
while atual.item != v: # enquanto nao encontrou
pai = atual
if v < atual.item: # caminha para esquerda
atual = atual.esq
filho_esq = True # é filho a esquerda? sim
else: # caminha para direita
atual = atual.dir
filho_esq = False # é filho a esquerda? NAO
if atual == None:
return False # encontrou uma folha -> sai
# fim laço while de busca do valor
# **************************************************************
# se chegou aqui quer dizer que encontrou o valor (v)
# "atual": contem a referencia ao No a ser eliminado
# "pai": contem a referencia para o pai do No a ser eliminado
# "filho_esq": é verdadeiro se atual é filho a esquerda do pai
# **************************************************************
# Se nao possui nenhum filho (é uma folha), elimine-o
if atual.esq == None and atual.dir == None:
if atual == self.root:
self.root = None # se raiz
else:
if filho_esq:
pai.esq = None # se for filho a esquerda do pai
else:
pai.dir = None # se for filho a direita do pai
# Se é pai e nao possui um filho a direita, substitui pela subarvore a direita
elif atual.dir == None:
if atual == self.root:
self.root = atual.esq # se raiz
else:
if filho_esq:
pai.esq = atual.esq # se for filho a esquerda do pai
else:
pai.dir = atual.esq # se for filho a direita do pai
# Se é pai e nao possui um filho a esquerda, substitui pela subarvore a esquerda
elif atual.esq == None:
if atual == self.root:
self.root = atual.dir # se raiz
else:
if filho_esq:
pai.esq = atual.dir # se for filho a esquerda do pai
else:
pai.dir = atual.dir # se for filho a direita do pai
# Se possui mais de um filho, se for um avô ou outro grau maior de parentesco
else:
sucessor = self.nosucessor(atual)
# Usando sucessor que seria o Nó mais a esquerda da subarvore a direita do No que deseja-se remover
if atual == self.root:
self.root = sucessor # se raiz
else:
if filho_esq:
pai.esq = sucessor # se for filho a esquerda do pai
else:
pai.dir = sucessor # se for filho a direita do pai
sucessor.esq = atual.esq # acertando o ponteiro a esquerda do sucessor agora que ele assumiu
# a posição correta na arvore
return True
def inOrder(self, atual):
if atual != None:
self.inOrder(atual.esq)
print(atual.item,end=" ")
self.inOrder(atual.dir)
def preOrder(self, atual):
if atual != None:
print(atual.item,end=" ")
self.preOrder(atual.esq)
self.preOrder(atual.dir)
def posOrder(self, atual):
if atual != None:
self.posOrder(atual.esq)
self.posOrder(atual.dir)
print(atual.item,end=" ")
def altura(self, atual):
if atual == None or atual.esq == None and atual.dir == None:
return 0
else:
if self.altura(atual.esq) > self.altura(atual.dir):
return 1 + self.altura(atual.esq)
else:
return 1 + self.altura(atual.dir)
def folhas(self, atual):
if atual == None:
return 0
if atual.esq == None and atual.dir == None:
return 1
return self.folhas(atual.esq) + self.folhas(atual.dir)
def contarNos(self, atual):
if atual == None:
return 0
else:
return 1 + self.contarNos(atual.esq) + self.contarNos(atual.dir)
def minn(self):
atual = self.root
anterior = None
while atual != None:
anterior = atual
atual = atual.esq
return anterior
def maxx(self):
atual = self.root
anterior = None
while atual != None:
anterior = atual
atual = atual.dir
return anterior
def caminhar(self):
print(" Exibindo em ordem: ",end="")
self.inOrder(self.root)
print("\n Exibindo em pos-ordem: ",end="")
self.posOrder(self.root)
print("\n Exibindo em pre-ordem: ",end="")
self.preOrder(self.root)
print("\n Altura da arvore: %d" %(self.altura(self.root)))
print(" Quantidade de folhas: %d" %(self.folhas(self.root)))
print(" Quantidade de Nós: %d" %(self.contarNos(self.root)))
if self.root != None: # se arvore nao esta vazia
print(" Valor minimo: %d" %(self.minn().item))
print(" Valor maximo: %d" %(self.maxx().item))
#### fim da classe ####
arv = Tree()
print("Programa Arvore Binaria")
opcao = 0
while opcao != 5:
print("***********************************")
print("Entre com a opcao:")
print(" --- 1: Inserir")
print(" --- 2: Excluir")
print(" --- 3: Pesquisar")
print(" --- 4: Exibir")
print(" --- 5: Sair do programa")
print("***********************************")
opcao = int(input("-> "))
if opcao == 1:
x = int(input(" Informe o valor -> "))
arv.inserir(x)
elif opcao == 2:
x = int(input(" Informe o valor -> "))
if arv.remover(x) == False:
print(" Valor nao encontrado!")
elif opcao == 3:
x = int(input(" Informe o valor -> "))
if arv.buscar(x) != None:
print(" Valor Encontrado")
else:
print(" Valor nao encontrado!")
elif opcao == 4:
arv.caminhar()
elif opcao == 5:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment