freeCodeCamp/guide/portuguese/miscellaneous/data-structure-linked-list/index.md

11 KiB
Raw Blame History

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

  1. 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.

  1. 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.

  1. 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

  1. 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 da head 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 X next .
  • O ponto X está ao next deste novo nó.
    `

Complexidade do Tempo: O (1)

  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 Temp next .
  • 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 Temp next .
  • Memória livre usada pelo nó Temp.
    `

Complexidade do Tempo: O (1)

  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; 
 } 

:rocket: Executar código

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") 

:rocket: Executar código

Vantagens

  1. 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.
  2. Inserção e exclusão do nó são facilmente implementadas em uma lista encadeada em qualquer posição.

Desvantagens

  1. Eles usam mais memória do que matrizes por causa da memória usada por seus ponteiros ( next e prev ).
  2. O acesso aleatório não é possível na lista vinculada. Temos que acessar os nós sequencialmente.
  3. É 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.