Escolar Documentos
Profissional Documentos
Cultura Documentos
Contents
1 Introdução ao Python 5
1.1 O que é Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.1 Características: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Vantagens do Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Instalação do Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.1 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.2 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.3 Mac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
4 Estruturas Condicionais 14
4.1 if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2 if-else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.3 if-elif-else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.4 Exercícios Práticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
5 Estruturas de Repetição 17
5.1 while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.2 for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.3 Instruções de Controle de Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.3.1 break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.3.2 continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
6 Orientação a Objetos 20
6.1 Introdução à Programação Orientada a Objetos . . . . . . . . . . . . . . . . . . . 20
6.1.1 Classes e Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
6.1.2 Atributos e Métodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
6.2 Herança, Polimorfismo e Encapsulamento . . . . . . . . . . . . . . . . . . . . . . . 21
6.2.1 Herança . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6.3 Polimorfismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.4 Encapsulamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.5 Exemplo prático . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6.6 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7 Estruturas de Dados 25
7.1 Definição e Importância . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.2 Classificação de Estruturas de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.3 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.3.1 Conceito e Utilização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.3.2 Operações Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.3.3 Vantagens e Desvantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.3.4 Atividade Prática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
7.4 Listas encadeadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.4.1 Conceito e Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.4.2 Operações Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.4.3 Vantagens e Desvantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.5 Lista Duplamente Encadeada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.5.1 Conceito e Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.5.2 Operações Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.5.3 Vantagens e Desvantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
7.5.4 Exemplo de Uso em Python: . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
7.6 Lista Circular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.6.1 Conceito e Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.6.2 Operações Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.6.3 Vantagens e Desvantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.6.4 Exemplo de Uso em Python: . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
7.7 Pilhas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.7.1 Conceito e Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.7.2 Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.7.3 Operações Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1 INTRODUÇÃO AO PYTHON
Neste capítulo, vamos explorar os conceitos fundamentais do Python, suas vantagens como
linguagem de programação e como instalar o Python em diferentes sistemas operacionais, in-
cluindo Windows, Linux e macOS.
1.1.1 CARACTERÍSTICAS:
• Sintaxe legível: A sintaxe do Python é projetada para ser clara e legível, enfatizando a
compreensão do código.
• Ampla biblioteca padrão: O Python possui uma biblioteca padrão abrangente, que fornece
uma ampla gama de módulos e funções prontos para uso.
• Facilidade de aprendizado: Python possui uma curva de aprendizado suave, o que o torna
uma ótima escolha para iniciantes em programação.
• Flexibilidade: Python pode ser usado para uma ampla variedade de tarefas, desde script-
ing simples até desenvolvimento web e científico.
• Produtividade: Python permite que você desenvolva soluções rapidamente, graças à sua
sintaxe clara e à vasta biblioteca padrão.
• Ampla biblioteca padrão: A biblioteca padrão do Python é extensa e oferece uma ampla
gama de recursos para diferentes necessidades de desenvolvimento.
• Integração: Python pode ser facilmente integrado a outras linguagens como C, C++, Java
e .NET.
1.3.1 WINDOWS
• Baixe o instalador do Python para Windows, adequado à arquitetura do seu sistema (32
bits ou 64 bits).
1.3.2 LINUX
• Se o Python não estiver instalado, abra o terminal e execute o seguinte comando, depen-
dendo da distribuição:
Ubuntu e Debian: sudo apt-get install python3
Fedora: sudo dnf install python3
CentOS: sudo yum install python3
Certifique-se de usar o comando correto para sua distribuição específica.
1.3.3 MAC
• O macOS geralmente vem com uma versão pré-instalada do Python. No entanto, é re-
comendável instalar uma versão mais recente.
python3 --version
• Visual Studio Code (VS Code): Um editor de código leve e altamente configurável, desen-
volvido pela Microsoft. Possui suporte a Python por meio de extensões e oferece recur-
sos poderosos para depuração e gerenciamento de projetos.
• Sublime Text: Um editor de código leve e personalizável que suporta Python com plugins.
É conhecido por sua velocidade e interface intuitiva.
• Atom: Um editor de código de código aberto desenvolvido pelo GitHub. Possui um ecos-
sistema de pacotes e plugins extensível, permitindo personalização e suporte a Python.
• PyDev: Uma IDE que se integra ao Eclipse, fornecendo recursos avançados para desen-
volvimento Python, como depuração e autocompletar.
Esses são apenas alguns exemplos, e você pode experimentar diferentes editores para encon-
trar aquele que melhor se adapta às suas necessidades.
pip --version
Um ambiente virtual é uma instância isolada do Python, onde você pode instalar pacotes e de-
pendências específicos para um projeto. Cada ambiente virtual possui seu próprio diretório de
instalação de pacotes, independente dos pacotes instalados no Python global do sistema.
• Isolamento de dependências: Com ambientes virtuais, você pode ter diferentes versões
de pacotes instalados para projetos diferentes, evitando conflitos de dependências.
• Facilidade de limpeza: Se você não precisa mais de um ambiente virtual, basta excluí-lo,
e todos os pacotes e dependências associados serão removidos.
Para criar um ambiente virtual Python, você pode usar a biblioteca venv, que está disponível
nas versões mais recentes do Python.
Criando um ambiente virtual no Windows:
• Abra o prompt de comando e navegue até o diretório onde deseja criar o ambiente virtual.
nome_do_ambiente\Scripts\activate
• Abra o terminal e navegue até o diretório onde deseja criar o ambiente virtual.
source nome_do_ambiente/bin/activate
Para sair do ambiente virtual, basta digitar o seguinte comando no prompt de comando ou ter-
minal:
deactivate
• Comentários: Os comentários são trechos de texto que não são executados pelo inter-
pretador Python. Eles são úteis para adicionar anotações ou explicar partes do código.
Em Python, os comentários são iniciados com o caractere ”” e vão até o final da linha.
if x > 5:
print("x é maior que 5")
# Ocorre um espaçamento depois da definição da estrutura if
• Variáveis: Em Python, as variáveis são usadas para armazenar valores. Você pode atribuir
um valor a uma variável usando o sinal de igual ”=”.
x = 10
nome = "Maria"
• Tipos de Dados: Python suporta vários tipos de dados, como números, strings, listas, tu-
plas, dicionários, entre outros. Esses tipos de dados são fundamentais para realizar op-
erações e manipular informações.
numero = 10
texto = "Olá, mundo!"
lista = [1, 2, 3, 4, 5]
dicionario = {"chave": "valor"}
• Exibindo Informações: Para exibir informações na tela, utilizamos a função print(). Ela
aceita um ou mais argumentos e os imprime na saída padrão.
print("Olá, mundo!")
3.3 FUNÇÕES
Funções são blocos de código reutilizáveis que realizam uma tarefa específica. Elas permitem
que você estruture seu código de forma modular e organizada.
• Definindo uma Função: Em Python, definimos uma função usando a palavra-chave def,
seguida pelo nome da função, parênteses que podem conter parâmetros e dois pontos.
O corpo da função é indentado.
def saudacao():
print("Olá, seja bem-vindo!")
saudacao()
• Parâmetros e Argumentos: Uma função pode receber parâmetros, que são valores forneci-
dos quando a função é chamada. Esses valores são chamados de argumentos.
def saudacao(nome):
print("Olá,", nome)
saudacao("João")
• Try-Except: Em Python, usamos blocos try e except para tratar exceções. O código den-
tro do bloco try é executado, e se ocorrer um erro, o código dentro do bloco except é
executado em vez de interromper o programa.
try:
resultado = 10 / 0
except ZeroDivisionError:
print("Erro: divisão por zero!")
try:
arquivo = open("dados.txt", "r")
# código para ler o arquivo
except FileNotFoundError:
print("Erro: arquivo não encontrado!")
finally:
arquivo.close()
Neste capítulo, exploramos os conceitos básicos da sintaxe Python, entrada e saída de da-
dos, o uso de funções e o tratamento de erros. Agora você está preparado para continuar sua
jornada no desenvolvimento Python e explorar recursos mais avançados da linguagem.
• Crie uma função que receba dois números como argumentos e retorne a soma deles.
• Implemente um programa que leia a idade do usuário e exiba uma mensagem informando
se ele é menor ou maior de idade.
• Escreva um programa que solicite três números do usuário e exiba o maior valor entre
eles.
• Crie uma função que verifique se um número é par ou ímpar e retorne True ou False.
4 ESTRUTURAS CONDICIONAIS
Neste capítulo, vamos explorar as estruturas condicionais em Python. As estruturas condi-
cionais permitem que você execute diferentes blocos de código com base em uma condição
ou conjunto de condições. Veremos a estrutura básica do if, a estrutura if-else e a estrutura
if-elif-else. Além disso, forneceremos exercícios práticos para reforçar o aprendizado.
4.1 IF
A estrutura básica do if em Python permite executar um bloco de código se uma condição for
avaliada como verdadeira.
if condição:
# bloco de código a ser executado se a condição for verdadeira
Exemplo:
idade = 18
if idade >= 18:
print("Você é maior de idade!")
4.2 IF-ELSE
A estrutura if-else permite que você execute um bloco de código se a condição for verdadeira
e outro bloco de código se a condição for falsa.
if condição:
# bloco de código a ser executado se a condição for verdadeira
else:
# bloco de código a ser executado se a condição for falsa
Exemplo:
idade = 16
4.3 IF-ELIF-ELSE
A estrutura if-elif-else permite que você avalie várias condições sequencialmente e execute
blocos de código correspondentes à primeira condição verdadeira encontrada. O bloco elif
(abreviação de ”else if”) é opcional e pode aparecer várias vezes.
if condição1:
# bloco de código a ser executado se a condição1 for verdadeira
elif condição2:
# bloco de código a ser executado se a condição2 for verdadeira
else:
# bloco de código a ser executado se nenhuma das condições anteriores for verdadei
Exemplo:
idade = 25
• Escreva um programa que determine se um ano é bissexto. Um ano é bissexto se for di-
visível por 4, mas não por 100, a menos que também seja divisível por 400.
• Escreva um programa que peça ao usuário que digite uma temperatura em Celsius e converta-
a para Fahrenheit. A fórmula para conversão é: fahrenheit = (celsius * 9/5) + 32.
• Escreva um programa que peça ao usuário que digite um número e verifique se o número
é par ou ímpar.
• Escreva um programa que peça ao usuário que digite um caractere e verifique se é uma
vogal ou consoante.
Neste capítulo, aprendemos sobre as estruturas condicionais em Python. Com o if, if-else
e if-elif-else, você pode controlar o fluxo do seu programa com base em condições específi-
cas. Pratique os exercícios para consolidar o seu entendimento dessas estruturas. No próximo
capítulo, abordaremos as estruturas de repetição em Python.
5 ESTRUTURAS DE REPETIÇÃO
Neste capítulo, exploraremos as estruturas de repetição em Python. Veremos como usar o loop
while e o loop for para executar blocos de código repetidamente. Também discutiremos as in-
struções de controle de loop para personalizar o comportamento de repetição. Além disso,
incluiremos exercícios práticos para aprimorar sua compreensão das estruturas de repetição.
5.1 WHILE
O loop while é usado quando você deseja repetir um bloco de código enquanto uma condição
for verdadeira. A estrutura básica do loop while é a seguinte:
while condição:
# Bloco de código a ser repetido
O bloco de código é repetido enquanto a condição for avaliada como verdadeira. Veja o
exemplo abaixo:
contador = 0
while contador < 5:
print(contador)
contador += 1
Neste exemplo, o bloco de código é repetido enquanto o valor da variável contador for
menor que 5. A cada iteração, o valor do contador é incrementado em 1.
5.2 FOR
O loop for é usado para iterar sobre uma sequência (como uma lista, uma string, um dicionário,
etc.) e executar um bloco de código para cada elemento da sequência. A estrutura básica do
loop for é a seguinte:
O bloco de código é repetido para cada elemento na sequência. Veja o exemplo abaixo:
Neste exemplo, o bloco de código é repetido para cada elemento da lista frutas, exibindo
cada fruta em uma linha separada.
Guia do Ninja Jounin Python 17
5 ESTRUTURAS DE REPETIÇÃO
5.3.1 BREAK
contador = 0
while True:
print(contador)
contador += 1
if contador == 5:
break
Neste exemplo, o loop while é interrompido quando o valor do contador atinge 5, mesmo
que a condição True ainda seja verdadeira.
5.3.2 CONTINUE
A instrução continue é usada para pular para a próxima iteração do loop, ignorando o restante
do bloco de código. Veja o exemplo abaixo:
for i in range(10):
if i % 2 == 0:
continue
print(i)
Neste exemplo, o bloco de código dentro do loop for é executado para todos os valores ím-
pares de i, enquanto os valores pares são ignorados usando a instrução continue.
• Crie um programa que solicite ao usuário que digite uma palavra e exiba cada caractere
em uma linha separada usando um loop for.
• Escreva um programa que solicite ao usuário que adivinhe um número entre 1 e 10. O
programa deve continuar solicitando palpites até que o usuário acerte o número, exibindo
uma mensagem de sucesso.
• Crie uma função que receba uma lista de números como argumento e retorne a soma de
todos os números pares na lista.
6 ORIENTAÇÃO A OBJETOS
Neste capítulo, vamos explorar o paradigma de programação orientada a objetos (POO) em
Python. Veremos os conceitos fundamentais da POO, como classes, objetos, atributos e méto-
dos. Além disso, abordaremos herança, polimorfismo e encapsulamento. A teoria será comple-
mentada com exemplos práticos em Python para ilustrar como aplicar esses conceitos.
Uma classe é uma estrutura que define o comportamento e os atributos de um objeto. Ela fun-
ciona como um molde para criar objetos específicos. Um objeto é uma instância de uma classe,
ou seja, uma representação concreta de um conceito abstrato. Veja o exemplo abaixo:
class Pessoa:
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
Neste exemplo, definimos a classe Pessoa com os atributos nome e idade. Em seguida, cri-
amos um objeto pessoa1 a partir dessa classe, passando valores para os atributos.
Atributos são características de um objeto, como nome, idade, cor, etc. Métodos são funções
associadas a uma classe ou a um objeto e definem seu comportamento. Veja o exemplo abaixo:
class Retangulo:
def __init__(self, largura, altura):
self.largura = largura
self.altura = altura
def calcular_area(self):
retangulo1 = Retangulo(10, 5)
area = retangulo1.calcular_area()
Neste exemplo, a classe Retângulo possui os atributos largura e altura. O método calcu-
lar_area() calcula a área do retângulo. Criamos um objeto retangulo1 e usamos o método cal-
cular_area() para obter a área do retângulo.
6.2.1 HERANÇA
A herança permite que uma classe herde atributos e métodos de outra classe. A classe que
herda é chamada de classe filha ou subclasse, enquanto a classe da qual é herdado é chamada
de classe pai ou superclasse. Veja o exemplo abaixo:
class Animal:
def __init__(self, nome):
self.nome = nome
def fazer_som(self):
pass
class Cachorro(Animal):
def fazer_som(self):
return "Au Au!"
cachorro1 = Cachorro("Rex")
som = cachorro1.fazer_som()
6.3 POLIMORFISMO
O polimorfismo permite que um objeto possa ser tratado como um objeto de qualquer uma de
suas classes ancestrais. Isso significa que diferentes classes podem ter métodos com o mesmo
nome, mas comportamentos diferentes. Veja o exemplo abaixo:
class Animal:
def fazer_som(self):
pass
class Cachorro(Animal):
def fazer_som(self):
return "Au Au!"
class Gato(Animal):
def fazer_som(self):
return "Miau!"
def fazer_barulho(animal):
return animal.fazer_som()
cachorro1 = Cachorro()
gato1 = Gato()
som_cachorro = fazer_barulho(cachorro1)
som_gato = fazer_barulho(gato1)
Neste exemplo, as classes Cachorro e Gato têm o método fazer_som(), mas cada um retorna
um som diferente. A função fazer_barulho() pode receber um objeto de qualquer uma das duas
classes e chamar o método fazer_som() apropriado.
6.4 ENCAPSULAMENTO
O encapsulamento é o princípio de ocultar os detalhes internos de um objeto e fornecer apenas
uma interface pública para interagir com ele. Em Python, usamos convenções de nomenclatura
para indicar a visibilidade dos atributos e métodos. Veja o exemplo abaixo:
Guia do Ninja Jounin Python 22
6 ORIENTAÇÃO A OBJETOS
class Carro:
def __init__(self, marca, modelo):
self.marca = marca
self.modelo = modelo
self.__velocidade = 0 # Atributo privado
def acelerar(self):
self.__velocidade += 10
def frear(self):
self.__velocidade -= 10
def obter_velocidade(self):
return self.__velocidade
Neste exemplo, o atributo __velocidade é definido como privado usando dois underscores
no início do nome. Isso indica que o atributo não deve ser acessado diretamente de fora da
classe. Em vez disso, usamos os métodos acelerar() e obter_velocidade() para interagir com o
atributo.
class ContaBancaria:
def __init__(self, numero_conta, saldo_inicial):
self.numero_conta = numero_conta
self.saldo = saldo_inicial
self.saldo -= valor
return valor
else:
print("Saldo insuficiente.")
def consultar_saldo(self):
return self.saldo
6.6 CONCLUSÃO
Neste capítulo, exploramos os conceitos fundamentais da orientação a objetos em Python.
Aprendemos sobre classes, objetos, atributos e métodos. Além disso, discutimos herança, polimor-
fismo e encapsulamento. Com os exemplos práticos, você pôde ver como aplicar esses con-
ceitos na prática. A orientação a objetos é uma poderosa abordagem de programação que pro-
move a modularidade e a reutilização de código. Continue praticando e explorando os recursos
da POO em Python para se tornar um programador mais eficiente e eficaz.
7 ESTRUTURAS DE DADOS
7.3 ARRAYS
Um array é uma estrutura de dados linear que armazena um conjunto de elementos do mesmo
tipo em uma ordem contígua na memória. Ele permite o acesso direto e eficiente aos elementos
através de um índice numérico. Os arrays são amplamente utilizados em programação para
armazenar e manipular coleções de dados de forma eficiente.
Em um array, cada elemento é identificado por um índice, que representa sua posição na
estrutura. O primeiro elemento geralmente tem o índice 0, o segundo tem o índice 1 e assim por
diante. Essa característica de acesso direto aos elementos através de índices torna os arrays
ideais para operações que exigem acesso aleatório aos dados.
Vantagens:
Acesso direto e rápido aos elementos através de índices. Utilização eficiente de memória,
pois os elementos são armazenados de forma contígua. Operações de busca e acesso aleatório
têm tempo de execução constante (O(1)). Desvantagens:
O tamanho do array é fixo após a sua criação, o que significa que não é possível aumentar ou
reduzir o número de elementos facilmente. Inserção e remoção de elementos no meio do array
requerem deslocamento dos elementos subsequentes, o que pode ser uma operação custosa
em termos de tempo. Os arrays só podem armazenar elementos do mesmo tipo.
• Implemente uma função que receba um array como parâmetro e retorne o valor máximo
presente no array.
• Crie uma função que receba um array como parâmetro e retorne uma nova lista contendo
apenas os números pares do array.
• Escreva uma função que receba dois arrays como parâmetros e retorne um novo array
que contenha os elementos comuns entre os dois arrays.
• Crie uma função que receba um array e um número como parâmetros e retorne a quan-
tidade de vezes que esse número aparece no array.
As listas ligadas, também conhecidas como linked lists, são estruturas de dados lineares que
consistem em uma sequência de nós, onde cada nó contém um valor e uma referência para o
próximo nó da lista. Diferentemente dos arrays, as listas ligadas não exigem que os elementos
estejam armazenados em locais de memória contíguos.
Cada nó em uma lista ligada possui dois componentes principais: o valor, que é o dado ar-
mazenado, e o ponteiro para o próximo nó. O último nó da lista tem um ponteiro nulo, indicando
o fim da lista.
Vantagens:
Tamanho flexível: As listas ligadas podem crescer e encolher conforme necessário, pois não
têm tamanho fixo como os arrays. Inserção e remoção eficientes: Adicionar ou remover ele-
mentos no início ou no final da lista ligada é uma operação eficiente, pois envolve apenas a atu-
alização dos ponteiros. Eficiência de memória: As listas ligadas são ideais quando não se sabe
o tamanho exato da coleção de dados antecipadamente, evitando desperdício de memória.
Desvantagens:
Acesso sequencial: A busca em uma lista ligada requer percorrer a lista do início até o el-
emento desejado, o que pode levar tempo linear, especialmente em listas grandes. Uso de
memória adicional: Cada nó em uma lista ligada requer um espaço adicional de memória para
armazenar o ponteiro para o próximo nó.
linked_list.insert(10)
linked_list.insert(20)
linked_list.insert(30)
linked_list.insert(40)
linked_list.remove(30)
print(linked_list.search(30)) # Saída: False
Neste exemplo, uma lista ligada simples é criada e alguns nós são inseridos. Em seguida, é
feita uma busca pelo valor 20 e, posteriormente, um nó com valor 30 é removido. As operações
básicas de uma lista ligada são demonstradas.
A lista duplamente encadeada, também conhecida como doubly linked list, é uma variação da
lista ligada em que cada nó possui uma referência tanto para o próximo nó quanto para o nó
anterior. Isso permite percorrer a lista em ambas as direções: da cabeça para a cauda e da
cauda para a cabeça.
Cada nó em uma lista duplamente encadeada contém três componentes principais: o valor
armazenado, um ponteiro para o nó anterior e um ponteiro para o próximo nó. O primeiro nó
da lista é chamado de cabeça, e o último nó é chamado de cauda. A cabeça tem seu ponteiro
anterior definido como nulo, e a cauda tem seu ponteiro próximo definido como nulo.
As operações básicas em listas duplamente encadeadas são semelhantes às da lista ligada, mas
com a capacidade adicional de percorrer a lista em ambas as direções. As principais operações
incluem:
Inserção: Permite adicionar um novo nó à lista duplamente encadeada.
Remoção: Permite remover um nó existente da lista duplamente encadeada.
Busca: Permite procurar um valor específico na lista duplamente encadeada.
Acesso: Permite acessar o valor de um nó em uma determinada posição na lista duplamente
encadeada.
Atualização: Permite alterar o valor de um nó existente na lista duplamente encadeada.
Vantagens:
Percorrendo em ambas as direções: A lista duplamente encadeada permite percorrer a lista
tanto da cabeça para a cauda quanto da cauda para a cabeça, o que pode ser útil em certos
cenários.
Remoção mais eficiente: A remoção de um nó em uma lista duplamente encadeada pode
ser mais eficiente em comparação com uma lista ligada, pois não é necessário percorrer a lista
a partir do início para encontrar o nó anterior ao nó a ser removido.
Flexibilidade de manipulação: Com os ponteiros para o próximo e o anterior, é possível re-
alizar operações complexas, como inserção ou remoção de nós em qualquer posição da lista.
Desvantagens:
Uso adicional de memória: Cada nó em uma lista duplamente encadeada requer espaço
adicional de memória para armazenar o ponteiro anterior, o que pode aumentar o consumo de
memória em comparação com uma lista ligada.
Complexidade de implementação: A manipulação dos ponteiros adicionais em uma lista du-
plamente encadeada pode tornar a implementação mais complexa em comparação com uma
lista ligada.
self.head = new_node
self.tail = new_node
else:
new_node.prev = self.tail
self.tail.next = new_node
self.tail = new_node
doubly_linked_list.insert(30)
doubly_linked_list.insert(40)
doubly_linked_list.remove(30)
print(doubly_linked_list.search(30)) # Saída: False
A lista circular é uma variação da lista ligada em que o último nó da lista tem uma referência
que aponta para o primeiro nó, formando um ciclo contínuo. Dessa forma, a lista circular não
tem um início ou fim definidos, e é possível percorrer a lista repetidamente.
Cada nó em uma lista circular possui um valor e um ponteiro para o próximo nó na sequên-
cia. O último nó da lista possui um ponteiro que aponta para o primeiro nó, fechando o ciclo.
As operações básicas em listas circulares são semelhantes às da lista ligada, mas com a capaci-
dade adicional de percorrer a lista repetidamente. As principais operações incluem:
Inserção: Permite adicionar um novo nó à lista circular.
Remoção: Permite remover um nó existente da lista circular.
Busca: Permite procurar um valor específico na lista circular.
Acesso: Permite acessar o valor de um nó em uma determinada posição na lista circular.
Atualização: Permite alterar o valor de um nó existente na lista circular.
Vantagens:
Complexidade de implementação: A manipulação dos ponteiros em uma lista circular pode
ser mais complexa do que em uma lista ligada simples.
Cuidado com ciclos infinitos: É importante garantir que exista uma condição de parada em
qualquer percurso ou iteração pela lista circular, para evitar loops infinitos.
Desvantagens:
if self.head == self.head.next:
self.head = None
else:
current.next = self.head.next
self.head = self.head.next
return
current = self.head
prev = None
while current.next != self.head:
prev = current
current = current.next
if current.value == value:
prev.next = current.next
return
circular_linked_list.remove(30)
print(circular_linked_list.search(30)) # Saída: False
Neste exemplo, uma lista circular simples é criada e alguns nós são inseridos. Em seguida, é
feita uma busca pelo valor 20 e, posteriormente, um nó com valor 30 é removido. As operações
básicas de uma lista circular são demonstradas.
7.7 PILHAS
Uma pilha, também conhecida como stack, é uma estrutura de dados linear que segue o princí-
pio LIFO (Last In, First Out), ou seja, o último elemento adicionado à pilha é o primeiro a ser
removido. Pense em uma pilha de pratos: o último prato colocado é o primeiro a ser retirado.
7.7.2 IMPLEMENTAÇÃO
Uma pilha pode ser implementada utilizando uma lista encadeada ou um array. Neste capítulo,
iremos implementar uma pilha utilizando uma lista encadeada.
Vantagens:
As pilhas são amplamente utilizadas em diversas aplicações, como:
Gerenciamento de chamadas de função em tempo de execução (utilizado na pilha de chamadas
do sistema).
Inversão de sequências ou expressões.
Avaliação de expressões matemáticas.
Desfazer ações em editores de texto ou softwares de desenho.
Backtracking em algoritmos de busca.
def is_empty(self):
return self.top is None
def pop(self):
if self.is_empty():
return None
else:
popped_value = self.top.value
self.top = self.top.next
return popped_value
def peek(self):
if self.is_empty():
return None
else:
return self.top.value
print(stack.peek()) # Saída: 30
stack.pop()
print(stack.peek()) # Saída: 20
Neste exemplo, uma pilha é criada utilizando uma lista encadeada. Alguns elementos são
inseridos utilizando a operação push(), e em seguida é feita uma verificação do elemento no
topo da pilha utilizando a operação peek(). Por fim, um elemento é removido utilizando a op-
eração pop() e novamente é feita uma verificação do elemento no topo da pilha. As operações
básicas de uma pilha são demonstradas.
7.8 FILAS
7.8.1 CONCEITO
Uma fila, também conhecida como queue, é uma estrutura de dados linear que segue o princípio
FIFO (First In, First Out), ou seja, o primeiro elemento adicionado à fila é o primeiro a ser re-
movido. Pense em uma fila de pessoas aguardando atendimento: a pessoa que chegou primeiro
é a primeira a ser atendida.
7.8.2 IMPLEMENTAÇÃO
Uma fila pode ser implementada utilizando uma lista encadeada ou um array. Neste capítulo,
iremos implementar uma fila utilizando uma lista encadeada.
def is_empty(self):
return self.front is None
def dequeue(self):
if self.is_empty():
return None
else:
dequeued_value = self.front.value
self.front = self.front.next
if self.front is None:
self.rear = None
return dequeued_value
def get_front(self):
if self.is_empty():
return None
else:
return self.front.value
print(queue.get_front()) # Saída: 10
queue.dequeue()
print(queue.get_front()) # Saída: 20
Neste exemplo, uma fila é criada utilizando uma lista encadeada. Alguns elementos são adi-
cionados utilizando a operação enqueue(), e em seguida é obtido o elemento no início da fila
utilizando a operação get_front(). Após isso, um elemento é removido utilizando a operação
dequeue() e novamente é obtido o elemento no início da fila. As operações básicas de uma fila
são demonstradas.
7.9.1 CONCEITO
Uma árvore binária é uma estrutura de dados hierárquica em que cada nó pode ter até dois
filhos: um filho à esquerda e um filho à direita. Cada nó em uma árvore binária é chamado de
Guia do Ninja Jounin Python 40
7 ESTRUTURAS DE DADOS
nó pai e pode ter no máximo dois filhos. Essa estrutura é amplamente utilizada em algoritmos
e estruturas de dados, pois permite representar relações hierárquicas e realizar operações de
busca, inserção e remoção de forma eficiente.
7.9.2 IMPLEMENTAÇÃO
Uma árvore binária pode ser implementada utilizando uma classe Node, em que cada objeto
Node representa um nó da árvore. Cada nó contém um valor e referências para o seu filho à
esquerda e para o seu filho à direita.
self.right = None
return False
7.10.1 CONCEITO
Uma árvore de busca binária, também conhecida como BST (Binary Search Tree), é uma árvore
binária especial em que os nós são organizados de forma que a chave de cada nó seja maior que
todas as chaves em sua subárvore esquerda e menor que todas as chaves em sua subárvore
direita. Essa propriedade permite realizar operações de busca, inserção e remoção de forma
eficiente.
7.10.2 IMPLEMENTAÇÃO
Uma árvore de busca binária pode ser implementada utilizando uma classe Node, semelhante
à implementação de uma árvore binária convencional. Cada nó contém um valor e referências
para seu filho à esquerda e filho à direita.
current_node = current_node.right
Neste exemplo, uma árvore de busca binária é criada e alguns nós são inseridos utilizando
a operação insert(). Em seguida, é realizada uma busca pelos valores 30 e 40 utilizando a oper-
ação search(). As operações básicas de uma árvore de busca binária são demonstradas.
7.11.1 CONCEITO
Uma árvore AVL é uma árvore de busca binária balanceada em que a diferença de altura en-
tre as subárvores esquerda e direita de cada nó (chamada de fator de balanceamento) é no
máximo 1. Essa propriedade garante que a árvore esteja sempre balanceada e mantenha um
desempenho eficiente em operações de busca, inserção e remoção.
7.11.2 IMPLEMENTAÇÃO
Uma árvore AVL é implementada utilizando uma classe Node, semelhante à implementação de
uma árvore de busca binária convencional. Cada nó contém um valor, referências para seu filho
à esquerda e filho à direita, além de um fator de balanceamento.
self.right = None
self.height = 1
balance_factor = self._get_balance_factor(root)
return root
y.right = z
z.left = T3
return y
y.left = z
z.right = T2
return y
Neste exemplo, uma árvore AVL é criada e alguns nós são inseridos utilizando a operação
insert(). Em seguida, é realizada uma busca pelos valores 30 e 40 utilizando a operação search().
As operações básicas de uma árvore AVL são demonstradas.