簡體   English   中英

基於鏈表的優先隊列

[英]Priority Queue based on Link List

方法,,add_by_priority" 給了我分段錯誤,我知道問題出現在,,get_prio" 方法中。 我試圖解決它或搜索它是否可以在其他任何地方工作,例如在“,,if”語句之外它編譯得很好。另外我不知道我是否正確地完成了優先級插入的整個算法(尤其是 while 之后的 2 行環形)

        #ifndef SNODE_H
        #define SNODE_H
        
        #include <iostream>
        
        template<typename TYPE>
        class SNode
        {
        
        private:
        
        TYPE _elem; //value of element
        
        SNode<TYPE>* _next_elem; //connection to next node
        
        int _prio; //priority
        
        public:
        
        SNode();
        
        SNode(const TYPE & elem, const SNode<TYPE>* next_elem, const int prio);
        
        TYPE &get_elem();
        
        SNode<TYPE>* get_next_elem();
        
        int &get_prio();
        
        void set_elem(const TYPE & elem);
        
        void set_next_elem(SNode<TYPE>& next_elem);
        
        void set_priority(const int & prio);
        
        bool operator<(SNode<TYPE> & Node);
        
        bool operator>(SNode<TYPE> & Node);
        
        };
        
        
        #endif
    

    #ifndef LINKED_LIST
    #define LINKED_LIST
    
    #include <iostream>
    #include "SNode.h"
    
    
    template<typename TYPE>
    class LinkedList
    {
    private:
    SNode<TYPE>* head;
    public:
    LinkedList(); //konstruktor bezparametryczny
    
    void add_by_priority(const TYPE& Node, const int &prio);
    void removeFront();
    
    void addFront(const TYPE& Node, const int &prio);
    
    const TYPE & front() const;
    bool empty() const;
    void print();
    
    
    
    
    };
    
    

    #include "SNode.h"
    
    template<typename TYPE>
    SNode<TYPE>::SNode(){}
    
    template<typename TYPE>
    SNode<TYPE>::SNode(const TYPE & elem, const SNode<TYPE>* next_elem, const int prio)
    {
    _elem=elem;
    
    next_elem= NULL;
    
    _prio = prio;
    }
    
    template<typename TYPE>
    TYPE &SNode<TYPE>::get_elem()
    {
        return _elem;
    }
    
    template<typename TYPE>
    SNode<TYPE>* SNode<TYPE>::get_next_elem()
    {
        return _next_elem;
    }
    
    template<typename TYPE>
    int &SNode<TYPE>::get_prio()
    {
        return _prio;
    
    }
    
    template<typename TYPE>
    void SNode<TYPE>::set_elem(const TYPE & elem)
    {
        _elem=elem;
    }
    
    template<typename TYPE>
    void SNode<TYPE>::set_next_elem( SNode<TYPE>& next_elem)
    {
    _next_elem = &next_elem;
    }
    
    template<typename TYPE>
    void SNode<TYPE>::set_priority(const int & prio)
    {
    _prio = prio;
    }
    
    template<typename TYPE>
    bool SNode<TYPE>::operator<(SNode<TYPE> & Node) 
    {
    if((*this).get_prio() > Node.get_prio())
        return true;
    return false;
    }
    
    template<typename TYPE>
    bool SNode<TYPE>::operator>(SNode<TYPE> & Node)
    {
    return !(*this<Node);
    }
    

    #include <iostream>
    #include "LinkedList.h"
    
    
    //inicjuje obiekt ktory nie poakzuje na nic (NULL)
    template<typename TYPE>
    LinkedList<TYPE>::LinkedList()
    {
        head = nullptr; 
    }
    
    
    //zwraca 1 element listy
    template<typename TYPE>
    const TYPE & LinkedList<TYPE>::front() const
    {
        return head->get_elem();
    }
    
    
    template<typename TYPE>
    void LinkedList<TYPE>::addFront(const TYPE& Node, const int &prio) 
    {
    
        SNode<TYPE>* temp = new SNode<TYPE>; //tworzymy nowa zmienna do, ktorej przypiszemy wartosc podanego argumentu
        temp->set_elem(Node); //podpisujemy wartosc
        temp->set_priority(prio); //podpisujemy priority
        temp->set_next_elem(*head); //podpisuje pod adres aktualnego poczatku
        head = temp; //nowa inicjalizacja poczatku temp staje sie head
    }
    
    
    template<typename TYPE>
    void LinkedList<TYPE>::removeFront() 
    {
    
        SNode<TYPE>* temp = head; //tworzymy zmienna ktora pokazuje na head zeby nie zgubic pamieci head
        head = head->get_next_elem(); //przestawiamy head na nastepny element
    
    delete temp; //usuwamy pamiec ktora byla pod head
    
    }
    
    
    template<typename TYPE>
    void LinkedList<TYPE>::print()
    {
    SNode<TYPE>* tmp = head; //podpisanie zmiennej pod wartosc i adres head(by od pcozatku printowac liste)
    while(tmp->get_next_elem() !=nullptr ) //jesli lista nie jest pusta
        {
            std::cout << tmp->get_elem() << std::endl;  //print wartosc pod adresem tmp
            tmp = tmp->get_next_elem(); //przestaw na kolejne miejsce
        }
        std::cout << tmp->get_elem() <<std::endl;
    }
    
    
    template<typename TYPE>
    bool LinkedList<TYPE>::empty() const
    {
    if(head == nullptr) //jesli head nie pokazuje na NULL true
        return true;
    else
        return false; //jesli head jest NULL to nie ma elementow bo nic na nic nie pokazuje
    }
    
    
    template<typename TYPE>
    void LinkedList<TYPE>::add_by_priority(const TYPE& Node, const int &prio)
    {
    
    SNode<TYPE>* start_temp; //zmienna pomocnicza by wyszukac odpowiednie miejsce 
    SNode<TYPE>* temp = new SNode<TYPE>; 
    start_temp = head; //ustaw zmienna na head (poczatek listy)
    
    temp->set_elem(Node); //podpisujemy wartosc
    temp->set_priority(prio); //podpisujemy priority
    
    
        if(prio < head->get_prio() || head == nullptr) //jesli head ma wiekszy prio niz nowe podane prio lub lista jest puste
            {

                temp->set_next_elem(*head); // pod temp podpisz head
                head = temp; //temp staje sie head (wstawienie Node) utworzenie i wstawienie nowego node z wyzszym priorytetem
            }
        else
            {

        
                while(start_temp->get_next_elem() != nullptr && start_temp->get_next_elem()->get_prio() < prio) //rob dopoki nie skonczy sie lista 
                {                                                                                     //lub znajdzie priorytet wiekszy od obecnego 
                    start_temp = start_temp->get_next_elem(); //przejdz na kolejny element listy
                }
    
    
        temp->set_next_elem(*start_temp->get_next_elem()); //wez nastepny element(petla zakonczyla sie element wczesniej)
    
        start_temp->set_next_elem(*temp); //ustawia nowy node w poprawnie wybranym miejscu
    
            }
    }
    

    #include <iostream>
    #include <stdlib.h>
    #include <fstream>
    #include <string.h>
    #include "LinkedList.cpp"
    #include "SNode.h"
    
    /*
    template<typename TYPE>
    struct Mess_prio
    {
    int _key;
    TYPE _mess;
    };
    */
    
    
    int main()
        {
        
    int value,size,prio;
    LinkedList<int> list;
    
    std::cout << " Pass list size: " <<std::endl;
    std::cin >> size;
    std::cout << std::endl;
    for(int i=0; i<size; i++)
    {
    std::cout << "Enter the value: " << std::endl;
    std::cin >> value;
    std::cout << std::endl;
    std::cout << "Enter the priority: " << std::endl;
    std::cin >> prio;
    std::cout << std::endl;
    list.add_by_priority(value,prio);
    
    }
    list.print();
    
        }

您的代碼中有幾個錯誤:

// OP CODE
template<typename TYPE>
    SNode<TYPE>::SNode(){}

不初始化 _next_elem,將其留在無效的 state 中。 此構造函數運行后不一定是 null。

// OP CODE
template<typename TYPE>
SNode<TYPE>::SNode(const TYPE & elem, const SNode<TYPE>* next_elem, const int prio)
{
    _elem=elem;
    next_elem= NULL;
    _prio = prio;
}

在這里,您確實將其設置為 null 但您設置的是 function 參數,而不是成員,並且您從未從 function 參數中讀取。 _next_elem 在此構造函數之后也未初始化。

// OP CODE
template<typename TYPE>
void SNode<TYPE>::set_next_elem( SNode<TYPE>& next_elem)
{
    _next_elem = &next_elem;
}

在這里,您存儲了 object 的地址,您只知道在調用 function 時它還活着。 沒有簡單的方法來檢測提供的 next_elem 的生命周期是否已經結束,並且您的指針懸空。 但假設這是一種可能性。

// OP CODE
template<typename TYPE>
bool SNode<TYPE>::operator<(SNode<TYPE> & Node) 
{
    if((*this).get_prio() > Node.get_prio())
        return true;
    return false;
}

一種更“自然”的寫法是:

// suggestion
template<typename TYPE>
bool SNode<TYPE>::operator<(SNode<TYPE> & Node) 
{
    return this->get_prio() > Node.get_prio();
}

LinkedList 代碼中的另一個問題

// OP CODE
template<typename TYPE>
LinkedList<TYPE>::LinkedList()
{
    head = nullptr; 
}

// OP CODE
template<typename TYPE>
void LinkedList<TYPE>::addFront(const TYPE& Node, const int &prio) 
{
...
    temp->set_next_elem(*head);
}

在這里,如果你創建一個 LinkedList,head 是 nullptr,但是如果你嘗試在這個列表上添加Front,突然你取消引用 null。

我停在這里。 請注意您的地址、指針、生命周期等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM