Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // 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();
- }
Add Comment
Please, Sign In to add comment