」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 優先隊列:詳細的數據結構和學習

優先隊列:詳細的數據結構和學習

發佈於2025-04-17
瀏覽:450

Priority Queue! Vamos destrinchar e aprender sobre essa parte de Estrutura de Dados.

Fila

Fila, assim como a Pilha, é uma especialização da Lista. Ela basea-se no fundamento FIFO - first in, first out, isso significa que o primeiro a entrar é o primeiro a sair. Em outras palavras, o mais “velho” da fila sai primeiro, para melhor compreensão leve em consideração uma fila de banco.

⚠️

Aplicações da Fila: Gerenciamento de processos em sistemas operacionais; Comunicação entre tarefas em programação concorrente; redes de computadores (impressões); respostas de requisições em servidor Web

Filas em si só permite a manipulação direta de dados nas extremidades.

public interface Queue {
    void enqueue(E value); //enfileira
    E dequeue(); //remove e desenfileira
    E first(); //retorna primeiro elemento
    int size(); //algumas literaturas se chama lenght()
    boolean isEmpty();
}

Fila de Prioridade

Assemelha-se ao comportamento de uma fila comum do dia a dia, mas agora encare que você está na fila de um banco e uma senhora entra na fila, todos deixam ela passar na frente pois a mesma tem maior PRIORIDADE por ser mais velha.

Na Estrutura de Dados Priority Queue cada nó tem um Key-Value, Key é a chave que guarda sua prioridade, Value é o valor do nó. Por padrão do Java, a Key é inicialmente numérica, podendo ser trocada pelo programador posteriormente.

O conjunto de uma Key e Value se chama Entry, logo a interface dessa E.D muda. Outros detalhes são: após a Key ser definida, ela não pode ser alterada. Caso dois nós tenham o mesmo valor de prioridade na Key o programador escolhe a regra.

public interface PriorityQueueOg {
    void insert(K key, V value);
    Entry remove();
    int size();
    boolean isEmpty();
}

Nas próximas estruturas, iremos usar as classes para Node e Entry, atributos de first, last e size, e o compareTo

A fila de prioridade se divide em dois: a ordenada (Sorted Priority Queue) e a desordenada (Unorted Priority Queue)

Sorted Priority Queue

Lista ordenada se preocupa logo em inserir o nó na posição certa, logo a remoção é fácil, só remover o primeiro (se o programador fazendo a E.D definir que o elemento de maior prioridade deve ficar no começo)

Para sabermos qual nó tem maior prioridade usamos compareTo, uma função de Collections que, através de seu retorno, podemos obter resultados cruciais para a execução dessa E.D, caso o retorno seja:

  • Negativo: Se o objeto que chama o método é "menor" que o objeto passado como parâmetro.
  • Zero: Se os objetos são iguais.
  • Positivo: Se o objeto que chama o método é "maior" que o objeto passado como parâmetro.

Insert

Para inserir deve verificar algumas coisas

1° passo → Criar um novo nó

Node newNode = new Node(key, value)

2° passo → Verificar se a Fila está vazia, se sim, colocar o Head e o Last como o novo nó, tendo em vista que será o único

        if(isEmpty()){
            first = newNode;
            last = newNode;
        }else{

3° passo → Se não for o único elemento da lista, deve verificar se o novo nó, comparado com o primeiro, tem maior prioridade ou não.

         if(compare(newNode, first)



3° passo → Compara depois com o último elemento da lista

             }else if(compare(newNode, last)>=0){
           //Se o nN for maior que o L
           //Significa que o número de nN é maior que L
           //Então bota o nN para ultimo
                newNode.previous=last;
                last.next=newNode;
                last = newNode;
            }else{

4° passo → Se não for todo o resto, só resta o meio! Para tal ato, precisamos fazer um nó auxiliar para ir percorrendo na frente do newNode (nN) e ir comparando os dois, a comparação acaba quando o auxNode aponta para nada, ou quando o nN for maior que o auxNode (maior, logo fica atrás dele na fila). Esse while serve para o aux ir andando e comparando o valor dos dois nós, quando achar, coloca o nN atrás do auxNode

            }else{
                //se nao for nada, está no meio
                //entao temos que achar entre qual dos meios
                Node auxNode = first;
                while(compare(newNode, auxNode)>0 && auxNode.next!=null){
                    //enquanto o newNode tiver prioridade maior que o auxiliar
                    //e o auxiliar tiver um proximo
                    auxNode = auxNode.next;
                }
                newNode.next = auxNode;
                newNode.previous = auxNode.previous;
            }
        }

Remove

O método remover no Sorted é bem mais simples pois, como já fora dito, a Fila já está toda organizada para ele.

1° passo → Como todo método Remove retorna o elemnto que ele irá tirar, o passo será criar uma Entry (Por que não um nó?)

        Entry max = maxPriority();

2° passo → Depois, como já vai eliminar o primeiro nó, basta apontar o First para o próximo do First

        first = first.next;

3° passo → Ver se tem só um elemento na Fila, pois se tiver, a Fila ficará vazia! Logo terá que apontar para null o F e L

        if(size==1){
            last = null;
            first = null;
        }else{

4° passo → Se não for o único elemento, significa que tem outros! Logo, quando tirar o primeiro no passo 2, o que antes era First ainda está lá sendo ligado pelo previous, então devemos:

       else{
            first.previous = null;
        }
        return max;

MaxPriority

Método que retorna o elemento de maior prioridade da lista, e como estamos na ordenada, apenas retorna o primeiro.

    public Entry maxPriority(){
        if(isEmpty()) throw new RuntimeException("PQ is empty!");
        return first.entry;
    }

Análise Assintótica

Método O(_)
size O(1)
isEmpty O(1)
insert O(n)
remove O(1)
maxPriority O(1)

Unsorted Priority Queue

A Fila desordenada é bem diferente da ordenada! Comecemos por seus métodos:

Insert

Para adicionar na unsorted, como e desordenada, não precisa se preocupar em qual local esse novo elemento vai ficar, apenas adiciona no final!

1° passo → Verifica se a lista está vazia, pois se estiver, o nó a ser adicionado será o primeiro (First) e o último (Last)

       Node newNode = new Node(key, value);
       if(isEmpty()){
        //se tiver vazia significa que vai ser o primeiro elemento
        first = newNode;
       }else{

2° passo → se não for vazia, basta se preocupar em adicionar esse nó no final!

       }else{
        //se não for vazia, vai ser adicionado no final
        newNode.previous = last;
        last.next = newNode;
       }
       last = newNode;
       size  ;

MaxPriority

O remove em Unsorted é bem mais complexo do que as míseras linhas de código do Sorted…

“Por quê?” você pergunta, devemos usar um método ( que na outra versão era bem mais simples também) chamado maxPriority, cujo objetivo é achar o nó de maior prioridade. Anteriormente ele foi ensinado de maneira simples com poucas linhas de código, agora, por não sabermos onde de fato está esse nó de maior prioridade, devemos percorrer a fila toda em busca dele! Então antes de vermos o remove em si, veremos o maxPriority.

1° passo → Sempre que queremos percorrer uma estrutura de dados, precisamos de dois nós: um auxiliar para ir sempre na frente, e o que queremos atingir (que nesse caso é o MaxPriority)

        Node max = first;
        Node aux = first.next;

2° passo → Esses dois irão percorrer dentro de um nó, só acaba quando o aux chegar ao null (final da fila). Faz o compare desses nós e se for negativo siginica que o aux é menor que o max, logo o max é o maior, atualizando o valor do max Node, e então faz o aux andar.

        while (auxNode!=null) {
           int c = compare(auxNode, maxPriority);
            if(c



Remove

1° passo → Em todos os emoves é criar uma variável que vai guardar o nóque vai ser removido. Nesse caso, já sabe qual será removido pois está chamando o método maxPriority

        Node toRemove = maxPriorityNode();

2° passo → Depois verifica se é o único elemento, se sim, F e L são nulls!

        if(size==1){
            //se só tem um elemento da fila, significa q ela fica vazia
            first = null;
            last = null;

3° passo → Se não for o único, há outras opções: se o max for o ultimo, elimina last, se for o primeiro, elimina o first, se não for nenhum dois dois, está no meio!

        }else{
            if(max == first){
                //se o max for o primeiro elemento, tira do começo
                first = first.next;
                first.previous = null;
            }else if(max == last){
                //se o max for o último elemento, tira do final
                last = last.previous;
                last.next = null;
            }

4° passo → Se estiver no meio, o max que está no povão terá que ser retirado, isso ocorre quando ninguém mais apontar para ele.

            }else{
                //se o max não for o primeiro ou o último, tira do meio
                max.previous.next = max.next;
                max.next.previous = max.previous;
            }
        }
        return max.entry;

Análise Assintótica

Método O(_)
size O(1)
isEmpty O(1)
insert O(1)
remove O(n)
maxPriority O(n)
版本聲明 本文轉載於:https://dev.to/amandafonseca/priority-queue-vamos-destrinchar-e-aprender-sobre-essa-parte-de-estrutura-de-dados-4ji5?1如有侵犯,請聯繫[email protected]刪除
最新教學 更多>
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-05-06
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示Achieving Text-Only Extraction with Python's MLStripperTo streamline the stripping process, the Python standard librar...
    程式設計 發佈於2025-05-06
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-05-06
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-05-06
  • Java中Lambda表達式為何需要“final”或“有效final”變量?
    Java中Lambda表達式為何需要“final”或“有效final”變量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    程式設計 發佈於2025-05-06
  • 編譯器報錯“usr/bin/ld: cannot find -l”解決方法
    編譯器報錯“usr/bin/ld: cannot find -l”解決方法
    錯誤:“ usr/bin/ld:找不到-l “ 此錯誤表明鏈接器在鏈接您的可執行文件時無法找到指定的庫。為了解決此問題,我們將深入研究如何指定庫路徑並將鏈接引導到正確位置的詳細信息。 添加庫搜索路徑的一個可能的原因是,此錯誤是您的makefile中缺少庫搜索路徑。要解決它,您可以在鏈接器命令中添...
    程式設計 發佈於2025-05-06
  • 切換到MySQLi後CodeIgniter連接MySQL數據庫失敗原因
    切換到MySQLi後CodeIgniter連接MySQL數據庫失敗原因
    無法連接到mySQL數據庫:故障排除錯誤消息要調試問題,建議將以下代碼添加到文件的末尾.//config/database.php並查看輸出: ... ... 迴聲'... echo '<pre>'; print_r($db['default']); echo '</pr...
    程式設計 發佈於2025-05-06
  • Go web應用何時關閉數據庫連接?
    Go web應用何時關閉數據庫連接?
    在GO Web Applications中管理數據庫連接很少,考慮以下簡化的web應用程序代碼:出現的問題:何時應在DB連接上調用Close()方法? ,該特定方案將自動關閉程序時,該程序將在EXITS EXITS EXITS出現時自動關閉。但是,其他考慮因素可能保證手動處理。 選項1:隱式關閉終...
    程式設計 發佈於2025-05-06
  • 為什麼在我的Linux服務器上安裝Archive_Zip後,我找不到“ class \” class \'ziparchive \'錯誤?
    為什麼在我的Linux服務器上安裝Archive_Zip後,我找不到“ class \” class \'ziparchive \'錯誤?
    class'ziparchive'在Linux Server上安裝Archive_zip時找不到錯誤 commant in lin ins in cland ins in lin.11 on a lin.1 in a lin.11錯誤:致命錯誤:在... cass中找不到類z...
    程式設計 發佈於2025-05-06
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-05-06
  • Java中假喚醒真的會發生嗎?
    Java中假喚醒真的會發生嗎?
    在Java中的浪費喚醒:真實性或神話? 在Java同步中偽裝喚醒的概念已經是討論的主題。儘管存在這種行為的潛力,但問題仍然存在:它們實際上是在實踐中發生的嗎? Linux的喚醒機制根據Wikipedia關於偽造喚醒的文章,linux實現了pthread_cond_wait()功能的Linux實現,...
    程式設計 發佈於2025-05-06
  • Java開發者如何保護數據庫憑證免受反編譯?
    Java開發者如何保護數據庫憑證免受反編譯?
    在java 在單獨的配置文件保護數據庫憑證的最有效方法中存儲憑據是將它們存儲在單獨的配置文件中。該文件可以在運行時加載,從而使登錄數據從編譯的二進製文件中遠離。 使用prevereness class import java.util.prefs.preferences; 公共類示例{ 首選...
    程式設計 發佈於2025-05-06
  • Java的Map.Entry和SimpleEntry如何簡化鍵值對管理?
    Java的Map.Entry和SimpleEntry如何簡化鍵值對管理?
    A Comprehensive Collection for Value Pairs: Introducing Java's Map.Entry and SimpleEntryIn Java, when defining a collection where each element com...
    程式設計 發佈於2025-05-06
  • Java數組中元素位置查找技巧
    Java數組中元素位置查找技巧
    在Java數組中檢索元素的位置 利用Java的反射API將數組轉換為列表中,允許您使用indexof方法。 (primitives)(鏈接到Mishax的解決方案) 用於排序陣列的數組此方法此方法返回元素的索引,如果發現了元素的索引,或一個負值,指示應放置元素的插入點。
    程式設計 發佈於2025-05-06
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-05-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3