Article image
Fernando Araujo
Fernando Araujo11/01/2024 13:45
Compartilhe

Listas em Python... E pilhas também!!!

  • #Python

Olá, dev!

 

           A Competição de artigos desta semana é sobre funções em Python.

           Para escrever este artigo, eu escolhi mostrar falar da estrutura lista do Python e vou mostrar como se implementa uma pilha em Python, usando listas.

           Além disso, eu também vou mostrar como se implementava uma pilha antigamente, com as linguagens FORTRAN e C.

 

 

Sumário

1.    Introdução

2.    Estrutura de dados em programação

3.    A estrutura de dados LISTA em Python

4.    A estrutura de dados PILHA

5.    Implementação da pilha em Python

6.    Implementação da pilha no passado

7.    Considerações finais

8.    Referências

 

1 – Introdução

 

           A Competição de artigos desta semana é sobre funções em Python.

 

           Neste artigo, eu vou tratar da estrutura LISTA em Python. Para exemplificar o seu uso em Python, eu vou implementar um exemplo que a aproveita para implementar uma estrutura de dados do tipo pilha, usando listas.

 

           Uma estrutura do tipo lista está presente em todas as linguagens de programação modernas, oferecidas de várias formas. Ela permite implementar algoritmos baseados em listas encadeadas, pilhas, filas, e outros modelos.

 

           A pilha é uma estrutura bem simples, porém ela é muito importante em qualquer linguagem de programação, pois permite a implementação de operações que sigam o princípio LIFO (“Last In, First Out”, ou primeiro que entra é o primeiro que sai).

 

           Eu também vou mostrar como se implementava uma pilha antigamente, nas linguagens FORTRAN e C.

 

 

2 – Estrutura de dados em programação

 

           Segundo Groner [1], a programação de computadores envolve escrever uma sequência de instruções para que o processador as execute. As instruções são formadas por comandos, que determinam as ações que devem ser executadas, e os dados com os quais os comandos irão operar.

 

           Cada linguagem de programação oferece diversos tipos de dados que podem ser usados para armazenar valores nas variáveis do programa. Entre os tipos de dados mais comuns, encontramos os inteiros, decimais, lógicos, caracteres, etc.

 

           Quando o algoritmo a ser implementado (a sequência de instruções) precisa de dados mais complexos, temos que usar estruturas mais complexas do que aqueles tipos de dados oferecidos pela linguagem.

 

           Nestes casos, além de criar novos tipos de dados, precisamos definir também quais as operações que poderão ser executadas nestes dados. Estes novos tipos de dados, juntamente com as operações que poderão ser usadas para operar com eles são as estruturas de dados.

 

           A lógica utilizada para resolver um problema é que vai indicar quais são as estruturas de dados mais adequadas para a sua resolução. Uma solução pode ser criada usando uma estrutura de dados menos adequada para um determinado problema, só que o algoritmo escolhido para implementar o código pode ficar mais complexo.

 

           Uma estrutura de dados mais adequada ao tipo de problema que se deseja resolver facilita o algoritmo para sua resolução e, consequentemente, o código ficará mais fácil e direto para escrever.

 

           Por exemplo, para implementar uma árvore genealógica, a estrutura de dados adequada seria uma árvore, já para implementar uma rede social, a melhor forma seria usar a estrutura de grafos, e assim por diante.

 

           Exemplos de estrutura de dados que não são disponibilizadas pelas são filas, pilhas, matrizes, árvores, grafos, etc.

 

           Os problemas que tenham um modelo de dados parecido com estes tipos de estruturas serão modelados de forma mais adequada com dados destes tipos.

 

           Nestes casos, será preciso criar uma estrutura de dados adequada à solução do problema.

 

           Por exemplo, se desejamos representar um modelo de rede social com grafos e a linguagem que iremos usar para codificar o problema não fornece um dado do tipo “grafo”, precisamos criar uma estrutura de dado para armazenar grafos e criar operações sobre este dado grafo.

 

           E isso precisa ser feito usando-se os tipos de dados oferecidos pela linguagem.

 

           No caso de uma pilha, a mesma coisa. Se a linguagem não oferece um dado do tipo PILHA, será preciso criar uma estrutura que armazene e tenha o comportamento de uma.

 

 

3 – A Estrutura de Dados LISTA em Python

 

           De acordo com [2], a linguagem Python oferece vários tipos de dados para armazenar as variáveis de um programa. Além disso, também oferece várias estruturas de dados complexas, com um conjunto amplo de funções e métodos para manipulação dos valores armazenados.

 

           As principais estruturas são:

·        Listas;

·        Tuplas;

·        Dicionários.

 

           As listas são coleções heterogêneas (de qualquer tipo, misturados) de itens, mutáveis (podem ser alteradas) e vamos falar detalhar mais sobre elas adiante. As tuplas são semelhantes às listas, mas são imutáveis (NÃO podem ser alteradas). Já os dicionários são listas de associações (chaves, valores), com chaves únicas e valores de qualquer tipo.

 

           A lista (list”) da linguagem Python implementa um vetor unidimensional de valores de qualquer tipo, inclusive misturados. Algumas operações que podemos implementar para uma lista são descritas a seguir, segundo a documentação oficial do Python [3], [4].

 

 

Criação de uma variável do tipo lista

 

           Uma variável lista pode ser definida com conteúdo vazio ou inicializada com valores, entre colchetes, como os exemplos a seguir:

 

vetor_vazio = [ ]

vetor_simples = [2, 1, 3]

vetor_de_livros = [“Código Limpo”, “Python Fluente”, “Arquitetura Limpa”]

vetor_heterogeneo = [10, 15, “DIO”, [1, 2, 3, 4], “100”]

 

 

Acesso aos valores armazenados

 

           Como todas as linguagens modernas, os índices do vetor são inteiros consecutivos, iniciados em 0. O acesso a um elemento individual é feito por meio de seu índice, entre colchetes. 

           

           Os exemplos a seguir serão sempre usarão os vetores originais criados na seção anterior, ou seja, sem considerar as possíveis alterações aplicadas pelos comandos dos exemplos.

 

print( vetor_de_inteiros )

será impresso: [2, 1, 3]

 

print( vetor_de_livros[2] )

Será impresso: Python Fluente

 

           

           O acesso aos valores armazenados no vetor também pode ser feito com índices negativos, sendo percorrido o vetor na ordem inversa. O índice do último item é sempre -1, o do penúltimo, -2, e assim por diante. Veja os exemplos:

 

print( vetor_de_livros[-1] )

Será impresso: Arquitetura Limpa

 

print( vetor_de_livros[-2] )

Será impresso: Python Fluente

 

 

Manipulação dos itens de uma lista

 

           O Python oferece várias funções e métodos para a manipulação de itens armazenados em uma lista.

 

A função mais comum aplicada a uma lista é:

 

·        len(lista) – retorna o comprimento (“length”) da lista, ou seja, a quantidade de itens armazenados nela.

Ex1: len(vetor_de_livros), retornando 3 (3 itens).

Ex2: len(vetor_heterogeneo), retornando 5 (5 itens, note que a lista [1, 2, 3, 4] é apenas um dos itens dessa lista).

 

 

           Já os métodos mais comumente aplicados a uma lista são:

 

·        append(item) – insere um item após o último item armazenado.

Ex: vetor_simples.append(8), resultando em [2, 1, 3, 8].

 

·        clear( ) – Remove todos os itens da lista, resultando em uma lista vazia.

Ex: vetor_heterogeneo.clear( ), resultando em [ ].

 

·        index(item) – Retorna o índice do primeiro elemento da lista cujo valor é igual a item.

Ex: vetor_heterogeneo.index(“DIO”), resultando em 2.

 

·        insert(i, item) – Insere um item na posição i.

Ex: vetor_simples.insert(2, 25), resultando em [2, 1, 25, 3 ].

 

·        pop(i) – remove da lista o item armazenado na posição i. Sem parâmetro, remove o último item da lista. O valor do item removido é retornado pelo método e pode ser utilizado no programa.

Ex1: vetor_heterpogeneo.pop(1), resultando em = [10, “DIO”, [1, 2, 3, 4], “100”].

Ex2: vetor_de_livros.pop(), resultando em [“Código Limpo”, “Python Fluente”] .

 

·        remove(item) – Remove o primeiro elemento da lista que tem valor item.

Ex: vetor_simples.remove(3), resultando em [1, 2].

 

·        sort( ) – Ordena os itens da lista. Os critérios da ordenação podem ser alterados por parâmetros adicionais.

Ex: vetor_simples.sort( ), resultando em [ 1, 2, 3 ].

 

 

 

4 – A estrutura de dados PILHA

image

                

           Este artigo só enfocará a estrutura de dados do tipo pilha, embora existam outras estruturas de dados complexas que possam ser criadas para resolver problemas em uma linguagem.

 

           Um exemplo simples (e prático) de uma pilha pode ser uma pilha de livros (ou de pratos). Quando você coloca mais um livro na pilha, ele sempre será colocado no topo da pilha, sobre os outros livros que já estão lá. E quando você tira um livro, sempre pega o que está no topo da pilha.

 

           Ou seja, um livro que entrou na pilha primeiro só vai sair dela quando todos os livros que estão sobre ele saírem de cima dele. Dizendo de outra forma, o último livro que foi colocado na pilha será o primeiro a ser retirado.

 

           Em português resumido, o último que entra é o primeiro que sai. Em inglês, seria “Last In, First Out” (L.I.F.O. ou LIFO). Este é o comportamento esperado para uma estrutura do tipo pilha (“stack”, em inglês).

 

           Numa pilha de números inteiros, o primeiro inteiro que entra é o primeiro inteiro que sai. Numa pilha de nomes, o primeiro nome que entra é o primeiro nome que sai. E assim por diante.

 

           Em geral, as linguagens de programação não oferecem este tipo de estrutura de dados nativamente. É preciso construir uma estrutura, a partir dos tipos de dados oferecidos.

 

           Uma das formas mais simples de criar uma pilha é com um vetor (“array”). Um vetor é uma estrutura de dados homogênea (só armazena dados do mesmo tipo), finita, e sequencial.

 

           Para ilustrar, veja esse exemplo de uma pilha a seguir:

 

image


 

 

 

           Esta é uma pilha de 5 posições, para armazenar valores inteiros. 3 delas já estão ocupadas. O primeiro valor a entrar na pilha foi o número 12, seguido do 5 e finalmente, do 23, que foi o último número colocado na pilha.

           

           Então, pode-se dizer que o número que está na base da pilha é o 12 e o que está no seu topo é o 23.

 

           Uma pilha só possui 2 comportamentos:

·        adicionar um novo elemento à pilha (empilhar; em inglês: “push”, que significa empurrar). O novo elemento adicionado entrará 1 posição após o topo da pilha. O número de elementos da pilha aumentará de 1 unidade;

 

·        remover um elemento da pilha (desempilhar; em inglês: “pop”, que significa estourar). Um elemento removido da pilha sairá dela e o elemento anterior a ele ficará no seu lugar no topo da pilha. O número de elementos da pilha diminuirá de 1 unidade.

 

           Para adicionar um novo número na pilha, por exemplo, 8, ele entrará após o valor do topo da pilha (23). A pilha passará a ter 4 posições ocupadas e o número 8 ficará no seu topo (veja a figura).

image


 

           Agora, para remover um elemento da pilha, terá que ser removido o elemento do topo (8). A pilha voltará a ter apenas 3 elementos e o número 23 estará novamente no topo da pilha, sendo o próximo a ser removido, caso essa operação seja repetida.

 

           Realizando uma nova operação de desempilhamento:


image

 

           E a pilha ficará assim:


image

 

 

 

           Para adicionar mais um elemento novo na pilha (10), ele entrará após o valor do topo da pilha (5). A pilha passará a ter 3 posições ocupadas novamente e o número 10 ficará no seu topo:

image


 

 

Existem duas situações especiais que podem ocorrer com uma pilha:

·        Pilha cheia - Se a pilha tiver uma quantidade finita de posições (como nesse exemplo, 5 posições) e todas as posições estiverem ocupadas. Nesse caso, não será possível adicionar um novo elemento;

·        Pilha vazia - Se a pilha ainda não tiver nenhum elemento armazenado. Neste caso, não será possível remover um elemento.

 

           Na implementação de uma pilha, estas condições devem ser identificadas pelo programa e tratadas de acordo.

 

           Representando as operações do exemplo acima por um vetor horizontal, fica mais fácil associar a implementação de uma pilha a um vetor oferecido por uma linguagem de programação:


image

 

 

 

           A pilha é uma estrutura de dados muito importante para a programação, seja em aplicações típicas do uso dela ou então como auxiliar em aplicações que usam outras estruturas.

 

           Segundo Karumanchi [5], algumas destas aplicações são:

           

·        Implementação de uma calculadora com notação polonesa (ou pós-fixada – POSIX), baseada na notação reversa, proposta pelo matemático polonês Jan Lukasiewicz, para se escrever expressões aritméticas sem o uso de parênteses. Por esta notação, primeiro são apresentados os operandos e só depois, o operador que da operação que vai ser aplicada;

·        Balanceamento de pares de parênteses (de símbolos, como colchetes e chaves também);

·        Conversão de bases numéricas;

·        Implementar recursão em funções;

·        Reverter cadeias de caracteres (“strings”);

·        Problemas usando backtracking, revisitando caminhos já passados;

·        Desfazer ações.

·        Armazenamento de variáveis e chamadas de métodos após ocorrer exceções de stack overflow;

 

 

           Da mesma forma que a pilha, podemos implementar também o tipo conhecido fila, que opera da forma FIFO (“First In, First Out”), ou seja, o primeiro que entra é o primeiro que sai. Um exemplo deste comportamento é uma fila de banco (ou de cinema).

 

 

 

5 – Implementação de uma PILHA em Python

 

           Python não possui uma estrutura de dados específica para implementação de uma pilha. No entanto, a linguagem, oferece a estrutura lista, que facilita muito a implementação de estruturas do tipo listas encadeadas, pilhas e filas.

 

           Usando uma variável do tipo lista (LIST), podemos simular as operações requeridas por uma pilha.

 

 

Versão 1 – usando programação procedural

 

           Esta versão simples usa um vetor para implementar a pilha, de tamanho indefinido, semelhante à figura abaixo, só que na figura a pilha tem um tamanho definido.


image

 

 

# código em python para gerar uma pilha e testar com números inteiros

 

def empilhar(pilha, elemento):
 pilha.append(elemento)
 
def desempilhar(pilha):
 if len(pilha) > 0:
return pilha.pop()
 else:
return None
 
def esta_vazia(pilha):
 return len(pilha) == 0
 
def imprimir(pilha):
 print(pilha)
 
# Programa de teste com inúmeros inteiros
 
pilha1 = []
 
empilhar(pilha1, 10)
empilhar(pilha1, 20)
empilhar(pilha1, 30)
print(pilha1) # imprime [10, 20, 30 ]
 
desempilhar(pilha1)
print(pilha1) # imprime [10, 20 ]
 
desempilhar(pilha1)
print(pilha1) # imprime [ 10 ]
 
desempilhar(pilha1)
print( esta_vazia(pilha1) ) # imprime True
imprimir(pilha1) # imprime [ ]
 
empilhar(pilha1, 40)
imprimir(pilha1) # imprime [ 40 ]

 

 

 

Versão 2 – usando classes (POO)

 

image

           Esta versão usou uma classe para o tipo de dado pilha, baseado neste exemplo geral da figura abaixo: 

 

# código em python para gerar uma pilha, usando classes (POO) e testar com strings (palavras)
 
class Pilha:
 def __init__(self):
self.pilha = []
 
 def empilhar(self, elemento):
self.pilha.append(elemento)
 
 def desempilhar(self):
if len(self.pilha) > 0:
 return self.pilha.pop()
else:
 return None
 
 def esta_vazia(self):
return len(self.pilha) == 0
 
 def tamanho(self):
return len(self.pilha)
 
 def topo(self):
if len(self.pilha) > 0:
 return self.pilha[-1]
else:
 return None
 
 def imprimir(self):
print(self.pilha)
 
 
# programa de teste usando strings (palavras)
 
pilha2 = Pilha( )
 
pilha2.empilhar( "Código Limpo" )
pilha2.empilhar( "Python Fluente" )
pilha2.empilhar( "Arquitetura Limpa" )
 
pilha2.imprimir( ) # imprime ["Código Limpo", "Python Fluente", "Arquitetura Limpa" ]
print(pilha2.topo( )) # imprime Arquitetura Limpa
 
pilha2.desempilhar( )
print(pilha2.topo( )) # imprime Python Fluente
 
pilha2.desempilhar( )
print(pilha2.topo( )) # imprime Código Limpo
 
pilha2.desempilhar( )
print(pilha2.esta_vazia( )) # imprime True
pilha2.imprimir( ) # imprime [ ]
 
pilha2.empilhar("Não Me Faça Pensar")
print(pilha2.tamanho( )) # imprime 1
pilha2.imprimir( ) # imprime ["Não Me Faça Pensar"]
 

 

           OBS: Estes dois programas foram testados no Google Colab e rodaram sem erros.

 

 

6 – Implementação da pilha no passado

 

           Como eu sou um bom dinossauro (Opa! Isso dá um bom nome para um filme!), já programei pilhas em várias linguagens, quase o mesmo número de vezes que já programei “Hello, world!”.

 

           Agora, vou mostrar como era programar uma pilha em linguagens mais antigas, como FORTRAN e C, que não ofereciam nenhuma estrutura de dados adequada que pudesse facilitar a tarefa.

           

           Em 1980, aprendi a programar em FORTRAN, numa das versões iniciais da linguagem (ver capa do livro na figura abaixo), perfurando cartões para um mainframe. Naquela época, a única estrutura disponibilizada pela linguagem para programação de um conjunto de objetos, homogêneos, era o vetor (ou “array”).


image

 

 

           Um programa em FORTRAN para criar uma pilha de inteiros, com funções básicas para inserir e remover elementos está mostrado no código a seguir:

 

program PilhaInteiros
 implicit none
 
 integer, parameter :: MAX_ITENS = 5
 integer :: pilha(MAX_ITENS)
 integer :: topo
 integer :: escolha, valor
 
 ! Inicializa o topo da pilha
 topo = 0
 
 ! Menu de ações
 do
 write(*,*) '----------------------'
 write(*,*) '1 - Empilhar (PUSH)'
 write(*,*) '2 - Desempilhar (POP)'
 write(*,*) '3 - Exibir Pilha (SHOW)'
 write(*,*) '4 - Sair (QUIT)'
 write(*,*) 'Escolha uma opção (1-4): '
 read(*,*) escolha
 
 select case(escolha)
 
 ! Opção Empilhar
 case(1)
   if (topo < MAX_ITENS) then
     write(*,*) 'Digite o valor a ser empilhado: '
     read(*,*) valor
     topo = topo + 1
     pilha(topo) = valor
     write(*,*) 'Valor empilhado!'
   else
     write(*,*) 'PILHA CHEIA! Não pode empilhar mais itens.'
   end if
 
 ! Opção Desempilhar
 case(2)
   if (topo > 0) then
     write(*,*) 'Valor desempilhado: ', pilha(topo)
     topo = topo - 1
   else
     write(*,*) 'PILHA VAZIA! Não tem item para desempilhar.'
   end if
 
 ! Opção Exibir
 case(3)
   if (topo > 0) then
     write(*,*) 'Conteúdo da pilha (primeiro item listado é topo da pilha):'
     do valor = topo, 1, -1
       write(*,*) pilha(valor)
     end do
   else
     write(*,*) 'PILHA VAZIA!'
   end if
 
 ! Opção Sair
 case(4)
   write(*,*) 'Fim do programa.'
   exit
 case default
   write(*,*) 'Opção inválida! Tente novamente.'
 end select
 end do
 
end program PilhaInteiros

 

 

 

           Em 1983, aprendi a programar na linguagem C, com o famoso livro de capa cor de rosa de Byan Kernigham e Richie (ver capa do livro na figura abaixo). Também numa das versões iniciais da linguagem, mas, já em um computador mais amigável e em terminal de texto. A linguagem oferecia um tipo de dados em que o usuário poderia criar sua própria estrutura de dados, por programação, chamada de struct, e toda estrutura de conjunto de dados, como vetores ou cadeia de caracteres (“string”), era implementada pelos famigerados apontadores (“pointers”).


image

 

           Naquela época, a única estrutura disponibilizada pela linguagem para programação de um conjunto de objetos, homogêneos, era o vetor (ou “array”).

 

           Uma pilha poderia ser implementada em C por meio de um vetor homogêneo, estático (tamanho fixo definido), ou por uma estrutura complexa do tipo lista encadeada, criando uma estrutura específica para isso, inclusive de um tipo único (homogêneo).

 

           Um código de uma pilha baseada em lista encadeada e estrutura criada pelo usuário é mostrado no código a seguir:

 

 

#include <stdio.h>
#include <stdlib.h>
 
// estrutura criada para ser um nó da pilha
struct stackNode {
int data; // define data as an int
struct stackNode *nextPtr; // stackNode pointer
};
 
typedef struct stackNode StackNode; // synonym for struct stackNode
typedef StackNode *StackNodePtr; // synonym for StackNode*
 
// protótipos
void push(StackNodePtr *topPtr, int info);
int pop(StackNodePtr *topPtr);
int isEmpty(StackNodePtr topPtr);
void printStack(StackNodePtr currentPtr);
void mostraMenu(void);
 
 
// Programa Principal
int main(void){
StackNodePtr stackPtr = NULL; // points to stack top
int valor = 0; // int input by user
 
mostraMenu();
printf("%s", "> ");
int escolha = 0; 
scanf("%d", &escolha);
 
// Loop do programa
while (escolha != 3) {
   switch (escolha) {
 
      case 1: // Opção Empilhar
         printf("%s", "Informe um inteiro: ");
         scanf("%d", &valor);
         push(&stackPtr, valor);
         printStack(stackPtr);
         break;
 
      case 2: // Desempilhar
         // if stack is not empty
         if (!isEmpty(stackPtr)) {
            printf("Desempilhado -> %d.\n", pop(&stackPtr));
         }
         printStack(stackPtr);
         break;
 
      default:
         puts("OPÇÃO INVÁLIDA!.\n");
         mostraMenu();
         break;
   }
 
printf("%s", "> ");
scanf("%d", &escolha);
}
 
puts("Fim do programa.");
}
 
 
// Mostra o menu
void mostraMenu(void) {
puts("Escolha uma opção:\n"
"1 Empilhar (push)\n"
"2 Desempilhar (pop)\n"
"3 Sair do programa");
}
 
// Insere um nó no topo da pilha
void push(StackNodePtr *topPtr, int info) {
StackNodePtr newPtr = malloc(sizeof(StackNode));
 
if (newPtr != NULL) {
   newPtr->data = info;
   newPtr->nextPtr = *topPtr;
   *topPtr = newPtr;
}
else { 
   printf("%d não inserido. Sem memória disponível.\n", info);
}
}
 
// Remove um nó do topo da pilha
int pop(StackNodePtr *topPtr) {
StackNodePtr tempPtr = *topPtr;
int popValue = (*topPtr)->data;
*topPtr = (*topPtr)->nextPtr;
free(tempPtr);
return popValue;
}
 
// Imprime o conteúdo da pilha
void printStack(StackNodePtr currentPtr) {
if (currentPtr == NULL) { 
   puts("PILHA VAZIA!\n");
}
else {
   puts("Conteúdo da pilha:");
   printf("[Topo ->]: ");
 
   while (currentPtr != NULL) { // Varre o conteúdo da pilha, do topo para a base
   printf("%d , ", currentPtr->data);
   currentPtr = currentPtr->nextPtr;
   }
 
   puts("[<- Base]\n");
}
}
 
// Testa se a pilha está vazia
int isEmpty(StackNodePtr topPtr) {
return topPtr == NULL;
}
 

 

 

           Em C, um a estrutura (tipo “struct”) permite ao programador criar um tipo de dado próprio, específico para sua aplicação, podendo misturar vários tipos de dados nele.

 

           Uma struct pode ter, também, um apontador para uma estrutura do mesmo tipo, possibilitando a criação de listas encadeadas, onde cada nó é uma instância da estrutura original.

 

           Este programa usou uma estrutura para criar um tipo de nó para um item da pilha e um apontador para uma estrutura de pilha, criando uma lista de nós do mesmo tipo, mas usada com os comportamentos de uma pilha (ver figura).

image


 

 

 

OBS: Estes dois programas foram testados no Replit e rodaram sem erros.

 

 

 

7 – Considerações finais

 

           Neste artigo, eu tratei da estrutura LISTA em Python. Foram apresentadas as características gerais desse tipo de dado na linguagem Python, bem como as operações que podem ser usadas com ela.

 

           No entanto, o foco maior foi dado em uma das possíveis utilizações do tipo lista, que é a pilha.

 

           Embora esta estrutura não esteja presente, nativamente, em nenhuma linguagem, ela pode ser implementada a partir de vetores (“arrays”), presentes em todas as linguagens, ou listas, presentes em muitas linguagens modernas.

 

           Para exemplificar o uso do tipo lista em Python, foram implementados dois exemplos de pilhas com a linguagem, uma usando vetores e outra usando classes.

 

           Como eu conheço outras linguagens antigas, também implementei 2 exemplos de pilhas, como era costume nos anos 80, usando a linguagens FORTRAN e C.

 

           Embora a pilha seja uma estrutura muito simples, seu uso na programação é muito importante, pois ela implementa operações do tipo LIFO (“Last In, first Out”), ou seja, o primeiro elemento que entra é o primeiro que sai.

 

           Da mesma forma que a pilha, com pequenas alterações, podemos implementar também o tipo conhecido FILA.

 

 

8 – Referências

 

[1] Loiane Groner, Learning Javascript Data Structures and Algorithms, 3rd Edition, Birmingham, 2018, Packt Publishing.

 

[2] Luciano Ramalho, Python Fluente, São Paulo, 2015, Novatec.


[3] Python.org, 3.1.3. Lists. Disponível em: <https://docs.python.org/3/tutorial/introduction.html#lists>. Acessado em: 10/01/2024.

 

[4] Python.org, 5.1. More on Lists. Disponível em: <https://docs.python.org/3/tutorial/datastructures.html#more-on-lists>. Acessado em: 10/01/2024.

 

[5] Narasimha Karumanchi, Data Structures And Algorithms Made Easy, 5th Edition, Bombay, 2015, CareerMonk Publishing.

Compartilhe
Comentários (4)
Germano
Germano - 11/01/2024 18:55

Gostei dos exemplos

Fernanda Cipriano
Fernanda Cipriano - 11/01/2024 15:24

ótimo artigo!!! você consegue explicar o assunto de uma maneira simples, mas ainda deixando transparecer a bagagem de experiência que carrega! parabéns :D

Fernando Araujo
Fernando Araujo - 11/01/2024 15:23

Obrigado, Luiz!

Estou me esforçando para manter o nível dos melhores artigos.

Estamos juntos nessa!!!

Luiz Café
Luiz Café - 11/01/2024 15:06

Olá Fernando, parabéns mais uma vez pelo seu artigo, a maneira como explica cada conteúdo faz com que seja possível imaginar a aplicação do código na prática, o que facilita o entendimento. Seus exemplos e o uso de imagens facilitam ainda mais entender o tema apresentado, simplesmente incrível .👏👏👏