ulfben icon

linked_list_2020_refactor (2 hours)

ulfben | PRO | 11/29/20 06:15:22 PM UTC (Edited) | 0 ⭐ | 733 👁️ | Never ⏰ | []
C++ |

6.4 KB

|

None

|

0 👍

/

0 👎

// linked_list.h
 
#ifndef LINKED_LIST_H_INCLUDED
#define LINKED_LIST_H_INCLUDED
 
// note: implementation required for pass
 
class linked_list 
{
   linked_list(linked_list&& rhs) = delete;
   linked_list(const linked_list& rhs) = delete;
   linked_list& operator=(const linked_list &rhs) = delete;
   linked_list& operator=(linked_list&& rhs) = delete;
    struct node
    {
        node();
        node(int value, node* next);
 
        int value_ = 0;
        node* next_ = nullptr;
    };
public:
   linked_list();
   ~linked_list();
 
   void push_front(int value);
   void push_back(int value);
   void insert(int value, int index);
   void pop_front();
   void pop_back();
   void remove(int index);
   void clear();
   int size() const noexcept;
   int front() const noexcept;
   int back() const noexcept;
   int at(int index) const noexcept;
   node* getNodeAt(int index) const noexcept;
   bool empty() const noexcept;
   bool isInRange(int index) const noexcept;
 
private:
   int count_;
   node *head_;
   node *tail_;
};
 
#endif // !LINKED_LIST_H_INCLUDED
 
// linked_list.cpp
 
#include "linked_list.h"
 
linked_list::node::node(int value, node *next)
   : value_(value)
   , next_(next)
{
 
}
 
linked_list::linked_list() 
   : count_(0)
   , head_(nullptr)
   , tail_(nullptr)
{
 
}
 
linked_list::~linked_list()
{
    clear();
}
 
void linked_list::push_front(int value) {
    head_ = new node{ value, head_ };
    if (empty()){
        tail_ = head_;      
    }
    count_++;
}
 
void linked_list::push_back(int value) {
    node* Tmp_Node = new node{ value, nullptr };
    if (empty()) {      
        head_ = Tmp_Node;       
    }else{          
        tail_->next_ = Tmp_Node;
    }
    tail_ = Tmp_Node;
    count_++;
}
 
void linked_list::insert(int value, int index)
{
    if (!(isInRange(index) || index == count_)){ //WARNING, count_ should not be valid. The test is wrong.
        return;
    }
    if (index == 0){        
        return push_front(value);
    }
    if (index == count_) { // If index is after tail. TODO: probably a logic error.     
        return push_back(value);
    }   
    node* infront = getNodeAt(index - 1);
    node* after = infront->next_;
    infront->next_ = new node{ value, after };  
    count_++;       
}
 
void linked_list::pop_front()
{
    if (empty()) {
        return; //TODO: do we want pop_front on empty containers to be allowed? consider exceptions
    }
    if (count_ == 1) // If the list has only 1 node.
    {
        delete head_;
        head_ = nullptr;
        tail_ = nullptr;
        count_--;
        return;
    }
    else // If the list has more than 1 node.
    {
        node* Tmp_Node;
        Tmp_Node = head_->next_;
        delete head_;
        head_ = Tmp_Node;
        count_--;
        return;
    }
    
}
 
void linked_list::pop_back(){
    if (empty()) {
        return;//TODO: pop back on empty should be undefined behavior
    }   
    /*node* secondToLast = getNodeAt(size() - 1);   
    delete tail_;
    secondToLast->next_ = nullptr;
    tail_ = secondToLast;
    count_--;
    if (empty()) {
        head_ = nullptr;
        tail_ = nullptr;
    }*/
    if (count_ == 1) // If the list has 1 node.
    {
        delete tail_;
        tail_ = nullptr;
        head_ = nullptr;
        count_--;
        return;
    }
    else // If list has more than 1 node.
    {
        node* Tmp_CurrentNode = head_;
        node* Tmp_PreviousNode = head_; // Initialized as head just to avoid warnings.
        int IterationCounter = 0;
 
        while (Tmp_CurrentNode != tail_)
        {
            if (IterationCounter == (count_ - 2)) // Captures the before last node.
            {
                Tmp_PreviousNode = Tmp_CurrentNode;
            }
 
            Tmp_CurrentNode = Tmp_CurrentNode->next_;
            IterationCounter++;
        }
 
        delete Tmp_CurrentNode;
        Tmp_PreviousNode->next_ = nullptr;
        tail_ = Tmp_PreviousNode;
        count_--;
        return;
    }
}
 
void linked_list::remove(int index) 
{
    if (isInRange(index)) // Validates if index exists in the list.
    {
        node* Tmp_Node;
 
        if (index == 0) // If index is head.
        {
            if (head_->next_ == nullptr) // If there is nothing after the head.
            {
                delete head_;
                head_ = nullptr;
                tail_ = nullptr;
                count_--;
                return;
            }
            else // If there is something after the head.
            {
                Tmp_Node = head_->next_;
                delete head_;
                head_ = Tmp_Node;
                count_--;
                return;
            }
        }
 
        node* Tmp_CurrentNode = head_;
        node* Tmp_PreviousNode = head_; // Initialized as head just to avoid warnings.
        int IterationCounter = 0;
 
        if (index == (count_ - 1)) // If index is tail.
        {
            while (IterationCounter != index)
            {
                if (IterationCounter == (index - 1)) // Captures the previous node.
                {
                    Tmp_PreviousNode = Tmp_CurrentNode;
                }
 
                Tmp_CurrentNode = Tmp_CurrentNode->next_;
                IterationCounter++;
            }
 
            delete Tmp_CurrentNode;
            Tmp_PreviousNode->next_ = nullptr;
            tail_ = Tmp_PreviousNode;
            count_--;
            return;
        }
        else // If index is in the middle.
        {
            while (IterationCounter != index) 
            {
                if (IterationCounter == (index - 1)) // Captures the previous node.
                {
                    Tmp_PreviousNode = Tmp_CurrentNode;
                }
 
                Tmp_CurrentNode = Tmp_CurrentNode->next_;
                IterationCounter++;
            }
 
            Tmp_Node = Tmp_CurrentNode->next_;
            delete Tmp_CurrentNode;
            Tmp_PreviousNode->next_ = Tmp_Node;
            count_--;
            return;
        }
    }
}
 
void linked_list::clear(){  
    while (!empty()) {
        pop_back(); //assumes pop_back assigns nullptr to members when empty 
    }
}
 
int linked_list::size() const noexcept {
   return count_;
}
 
int linked_list::front() const noexcept {
    if (head_ == nullptr){
        return -1;  //WARNING: error sentinel value is a valid int value.   
    }
    return head_->value_;
}
 
int linked_list::back() const noexcept {
    if (tail_ == nullptr){
        return -1;  //WARNING: error sentinel value is a valid int value.   
    }
    return tail_->value_;   
}
 
int linked_list::at(int index) const noexcept {
    if (!isInRange(index)) {        
        return -1; //WARNING: error sentinel value is a valid value.        
        //invalid indexes should perhaps throw an exception, or assert.
    }
    node* tmp = getNodeAt(index);
    return tmp ? tmp->value_ : -1;
}
 
linked_list::node* linked_list::getNodeAt(int index) const noexcept {
    if (!isInRange(index)) {
        return nullptr;
    }
    node* temp = head_;
    for (int i = 0; i < index && temp->next_; i++) {
        temp = temp->next_;
    }
    return temp;
}
 
bool linked_list::empty() const noexcept{
    return count_ <= 0; //TODO: change count_ to std::size_t
}
 
bool linked_list::isInRange(int index) const noexcept{
    return !empty() && index > -1 && index < size();        
}
 

Comments

  • Yuizcko icon
    05/18/26 12:57:45 PM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400