11 KiB
title | localeTitle |
---|---|
Data Structure Linked List | Lista vinculada da estrutura de dados |
Assim como uma guirlanda é feita com flores, uma lista vinculada é composta de nós. Nós chamamos cada flor nesta guirlanda particular para ser um nó. E cada um dos pontos do nó para o próximo nó nesta lista, assim como ele tem dados (aqui é tipo de flor).
Tipos
- Lista unicamente vinculada
As listas unicamente ligadas contêm nós que possuem um campo de data
, bem como um next
campo, que aponta para o próximo nó na sequência. As operações que podem ser executadas em listas unicamente vinculadas são inserção, exclusão e passagem.
`
Singly Link List
head
|
|
+-----+--+ +-----+--+ +-----+------+
| 1 |o-----> | 2 |o-----> | 3 | NULL |
+-----+--+ +-----+--+ +-----+------+
`
Aplicação
Implementação interna do CPython, os frames e as variáveis avaliadas são mantidos em uma pilha.
Para isso, precisamos fazer uma iteração somente para a frente e para a cabeça, portanto, apenas a lista vinculada é usada.
- Lista Duplicada Vinculada
As listas duplamente encadeadas contêm o nó que tem o campo de data
, o next
campo e outro campo de link prev
apontando para o nó anterior na sequência.
`
Lista Duplicada Vinculada
head
|
|
+------+-----+--+ +--+-----+--+ +-----+------+
| | |o------> | |o------> | | |
| NULL | 1 | | 2 | | 3 | NULL |
| | | <------o| | <------o| | |
+------+-----+--+ +--+-----+--+ +-----+------+
`
Aplicação
O cache do navegador, que permite que você aperte o botão BACK e FORWARD. Aqui, precisamos manter uma lista duplamente vinculada, com URLs
como campo de dados, para permitir o acesso em ambas as direções. Para ir ao URL anterior, usaremos o campo prev
e, para ir para a próxima página, usaremos o next
campo.
- Lista vinculada circular
Listas ligadas circulares é uma lista ligada unicamente na qual o último nó, o next
campo aponta para o primeiro nó na sequência.
`
Lista vinculada circular
head
|
|
+-----+--+ +-----+--+ +-----+--+
-> | 1 | o -----> | 2 | o -----> | 3 | o ----
| + ----- + - + + ----- + - + + ----- + - + |
| |
`
Aplicação
Problema de timesharing resolvido pelo sistema operacional.
Em um ambiente de tempo compartilhado, o sistema operacional deve manter uma lista de usuários presentes e deve alternadamente permitir que cada usuário use uma pequena parte do tempo da CPU, um usuário por vez. O sistema operacional selecionará um usuário, permitirá que ele use uma pequena quantidade de tempo de CPU e passará para o próximo usuário.
Para este aplicativo, não deve haver nenhum ponteiro NULL, a menos que não haja absolutamente ninguém solicitando tempo de CPU, ou seja, a lista está vazia.
Operações básicas
- Inserção
Para adicionar um novo elemento à lista.
`
Inserção no começo
- Crie um novo nó com dados fornecidos.
- Aponte o novo nó ao
next
dahead
antiga. - Ponto de
head
a este novo nó.
Inserção no meio / fim
Inserção após o nó X.
- Crie um novo nó com dados fornecidos.
- Aponte o novo nó ao
next
do antigo Xnext
. - O ponto X está ao
next
deste novo nó.
`
Complexidade do Tempo: O (1)
- Eliminação
Para excluir o elemento existente da lista.
`
Exclusão no começo
- Obter o nó apontado pela
head
como Temp. - Ponto de
head
para o Tempnext
. - Memória livre usada pelo nó Temp.
Exclusão no meio / fim
Exclusão após o nó X.
- Obtenha o nó apontado por
X
como Temp. - Do Ponto X
next
à da Tempnext
. - Memória livre usada pelo nó Temp.
`
Complexidade do Tempo: O (1)
- Traversing
Para viajar pela lista.
`
Traversal
- Obter o nó apontado pela
head
como atual. - Verifique se Current não é nulo e exiba-o.
- Ponto atual para o atual
next
e passar para o passo acima.
`
Complexidade do tempo: O (n) // Aqui n é o tamanho da lista de links
Implementação
Implementação de C ++ da lista ligada individualmente
// Header files
#include <iostream>
struct node
{
int data;
struct node *next;
};
// Head pointer always points to first element of the linked list
struct node *head = NULL;
Imprimindo dados em cada nó
// Display the list
void printList()
{
struct node *ptr = head;
// Start from the beginning
while(ptr != NULL)
{
std::cout << ptr->data << " ";
ptr = ptr->next;
}
std::cout << std::endl;
}
Inserção no começo
// Insert link at the beginning
void insertFirst(int data)
{
// Create a new node
struct node *new_node = new struct node;
new_node->data = data;
// Point it to old head
new_node->next = head;
// Point head to new node
head = new_node;
std::cout << "Inserted successfully" << std::endl;
}
Exclusão no começo
// Delete first item
void deleteFirst()
{
// Save reference to head
struct node *temp = head;
// Point head to head's next
head = head->next;
// Free memory used by temp
temp = NULL:
delete temp;
std::cout << "Deleted successfully" << std::endl;
}
Tamanho
// Find no. of nodes in link list
void size()
{
int length = 0;
struct node *current;
for(current = head; current != NULL; current = current->next)
{
length++;
}
std::cout << "Size of Linked List is " << length << std::endl;
}
Procurando
// Find node with given data
void find(int data){
// Start from the head
struct node* current = head;
// If list is empty
if(head == NULL)
{
std::cout << "List is empty" << std::endl;
return;
}
// Traverse through list
while(current->data != data){
// If it is last node
if(current->next == NULL){
std::cout << "Not Found" << std::endl;
return;
}
else{
// Go to next node
current = current->next;
}
}
// If data found
std::cout << "Found" << std::endl;
}
Exclusão após um nó
// Delete a node with given data
void del(int data){
// Start from the first node
struct node* current = head;
struct node* previous = NULL;
// If list is empty
if(head == NULL){
std::cout << "List is empty" << std::endl;
return ;
}
// Navigate through list
while(current->data != data){
// If it is last node
if(current->next == NULL){
std::cout << "Element not found" << std::endl;
return ;
}
else {
// Store reference to current node
previous = current;
// Move to next node
current = current->next;
}
}
// Found a match, update the node
if(current == head) {
// Change head to point to next node
head = head->next;
}
else {
// Skip the current node
previous->next = current->next;
}
// Free space used by deleted node
current = NULL;
delete current;
std::cout << "Deleted succesfully" << std::endl;
}
Implementação de Python da Lista Simplesmente Vinculada
class Node(object):
# Constructor
def __init__(self, data=None, next=None):
self.data = data
self.next = next
# Function to get data
def get_data(self):
return self.data
# Function to get next node
def get_next(self):
return self.next
# Function to set next field
def set_next(self, new_next):
self.next = new_next
class LinkedList(object):
def __init__(self, head=None):
self.head = head
Inserção
# Function to insert data
def insert(self, data):
# new_node is a object of class Node
new_node = Node(data)
new_node.set_next(self.head)
self.head = new_node
print("Node with data " + str(data) + " is created succesfully")
Tamanho
# Function to get size
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.get_next()
print("Size of link list is " + str(count))
Procurando
# Function to search a data
def search(self, data):
current = self.head
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
current = current.get_next()
if current is None:
print("Node with data " + str(data) + " is not present")
else:
print("Node with data " + str(data) + " is found")
Exclusão após um nó
# Function to delete a node with data
def delete(self, data):
current = self.head
previous = None
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
previous = current
current = current.get_next()
if current is None:
print("Node with data " + str(data) + " is not in list")
elif previous is None:
self.head = current.get_next()
print("Node with data " + str(data) + " is deleted successfully")
else:
previous.set_next(current.get_next())
print("Node with data " + str(data) + " is deleted successfully")
Vantagens
- As listas vinculadas são uma estrutura de dados dinâmica, que pode aumentar e diminuir, alocar e desalocar a memória enquanto o programa está em execução.
- Inserção e exclusão do nó são facilmente implementadas em uma lista encadeada em qualquer posição.
Desvantagens
- Eles usam mais memória do que matrizes por causa da memória usada por seus ponteiros (
next
eprev
). - O acesso aleatório não é possível na lista vinculada. Temos que acessar os nós sequencialmente.
- É mais complexo que array. Se um idioma oferecer suporte à verificação de limite de matriz automaticamente, os Arrays o servirão melhor.
Nota
Nós temos que usar free () em C e delete em C ++ para liberar o espaço usado pelo nó deletado, enquanto, em Python e Java, o espaço livre é coletado automaticamente pelo coletor de lixo.