Singly-linked list data structure implementation











up vote
0
down vote

favorite












This code seems to work correctly. I would appreciate any comments on how to improve the code, e.g. readability, algorithms, const-correctness, memory, anything else I am forgetting?
Also, for the function swap_values, would it make more sense to swap two nodes instead of just values of the nodes and why?



SinglyLinkedList.hpp



#pragma once

#include <iostream>

class SinglyLinkedList {
private:
struct ListNode {
int value;
std::shared_ptr<ListNode> next;
ListNode(int val) : value(val), next(nullptr) {}
};

std::shared_ptr<ListNode> head;
std::shared_ptr<ListNode> tail;

std::shared_ptr<ListNode> find (int val) const;

public:
SinglyLinkedList();

void print_list () const;
void push_back (int val);
void pop_back ();
void push_front (int val);
void pop_front ();
size_t get_size () const;
bool search (int val) const;
void swap_values (int val1, int val2);
void remove_nodes (int val);
void reverse ();

~SinglyLinkedList();

};


SinglyLinkedList.cpp



#include "SinglyLinkedList.hpp"


SinglyLinkedList::SinglyLinkedList () : head (nullptr), tail (nullptr) {

}

void SinglyLinkedList::print_list () const {
// O(n)
if (head) {
std::shared_ptr<ListNode> tempNode = head;
while (tempNode) {
std::cout << tempNode->value << " ";
tempNode = tempNode->next;
}
std::cout << "n";
} else {
std::cout << "List is empty.n";
}
}

void SinglyLinkedList::push_back(int val) {
// O(n)
std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
if (head) {
std::shared_ptr<ListNode> tempNode = head;
while (tempNode != tail) {
tempNode = tempNode->next;
}
tempNode->next = currNode;
tail = currNode;
} else {
head = currNode;
tail = currNode;
}
}

void SinglyLinkedList::pop_back () {
// O(n)
if (!head) {
std::cout << "List is empty.n";
return;
}
if (head == tail) {
head = nullptr;
tail = nullptr;
return;
}
std::shared_ptr<ListNode> currNode = head;
while (currNode->next != tail) {
currNode = currNode->next;
}
tail = currNode;
currNode->next = nullptr;
}

void SinglyLinkedList::push_front (int val) {
// O(1)
std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
currNode->next = head;
head = currNode;
}

void SinglyLinkedList::pop_front () {
// O(1)
if (!head) {
std::cout << "List is empty.n";
return;
}
std::shared_ptr<ListNode> currNode = head;
head = head->next;
currNode->next = nullptr;
}

size_t SinglyLinkedList::get_size () const {
// O(n)
size_t listSize = 0;
std::shared_ptr<ListNode> currNode = head;
while (currNode) {
++listSize;
currNode = currNode->next;
}

return listSize;
}

bool SinglyLinkedList::search (int val) const {
// O(n)
if (!head) {
std::cout << "List is empty.n";
return false;
}
std::shared_ptr<ListNode> currNode = head;
while (currNode) {
if (currNode->value == val) {
//std::cout << "Value " << val << " is in the listn";
return true;
}
currNode = currNode->next;
}
//std::cout << "Value " << val << " is not in the list.n";
return false;
}
std::shared_ptr<SinglyLinkedList::ListNode> SinglyLinkedList::find (int val) const {
// O(n)
if (!head) {
return nullptr;
}
std::shared_ptr<ListNode> currNode = head;
while (currNode) {
if (currNode->value == val) {
return currNode;
}
currNode = currNode->next;
}
return nullptr;
}

void SinglyLinkedList::swap_values (int val1, int val2) {
// swap is O(1), find is O(n)
// Should I be swapping nodes instead of values?
std::shared_ptr<ListNode> val1Node = find (val1);
std::shared_ptr<ListNode> val2Node = find (val2);

if (!val1Node) {
std::cout << "Value " << val1 << " is not in the list.n";
return;
}
if (!val2Node) {
std::cout << "Value " << val2 << " is not in the list.n";
return;
}

int tempNodeVal = val1Node->value;
val1Node->value = val2Node->value;
val2Node->value = tempNodeVal;
}

void SinglyLinkedList::remove_nodes (int val) {
if (!head) {
std::cout << "List is empty.n";
return;
}
std::shared_ptr<ListNode> prevNode = nullptr;
std::shared_ptr<ListNode> currNode = head;
while (currNode) {
if (currNode->value == val) {
// val found - remove
if (!prevNode) {
// delete head node
if (head == tail) {
head = nullptr;
tail = nullptr;
return;
}
head = head->next;
prevNode = currNode;
currNode = currNode->next;
prevNode->next = nullptr;
prevNode = nullptr;
} else if (currNode == tail) {
// delete tail node
tail = prevNode;
prevNode->next = nullptr;
currNode->next = nullptr;
} else {
prevNode->next = currNode->next;
currNode->next = nullptr;
currNode = prevNode->next;
}
} else {
// val not found
prevNode = currNode;
currNode = currNode->next;
}
}
}

void SinglyLinkedList::reverse () {
// O(n)
if (!head || head == tail) {
return;
}
std::shared_ptr<ListNode> currNode = head;
std::shared_ptr<ListNode> prevNode = nullptr;
std::shared_ptr<ListNode> nextNode = nullptr;
head = nullptr;
tail = head;
while (currNode) {
nextNode = currNode->next;
currNode->next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
head = prevNode;
}

SinglyLinkedList::~SinglyLinkedList () {

}


main.cpp



#include "SinglyLinkedList.hpp"

int main() {

// List init
SinglyLinkedList myList;

std::cout << "Print list: n";
myList.print_list();
std::cout << "List size: " << myList.get_size() << "n";

// Add nodes to the back of the list
myList.push_back(2);
myList.push_back(4);
myList.push_back(3);
myList.push_back(1);
std::cout << "Print list: n";
myList.print_list();
std::cout << "List size: " << myList.get_size() << "n";

// Add nodes to the front of the list
myList.push_front(5);
myList.push_front(7);
myList.push_front(6);
std::cout << "Print list: n";
myList.print_list();
std::cout << "List size: " << myList.get_size() << "n";

// Pop nodes from the front of the list
myList.pop_front();
myList.pop_front();
std::cout << "Print list: n";
myList.print_list();
std::cout << "List size: " << myList.get_size() << "n";

// Pop nodes from the back of the list
myList.pop_back();
myList.pop_back();
std::cout << "Print list: n";
myList.print_list();
std::cout << "List size: " << myList.get_size() << "n";

// Check if node with specific velue is in the list
int valToSearch = 3;
bool foundVal = myList.search(valToSearch);
if (foundVal) {
std::cout << valToSearch << " is in the list.n";
} else {
std::cout << valToSearch << " is not in the list.n";
}

// Swap the values of two nodes
myList.push_back(7);
myList.push_back(8);
myList.push_back(9);
myList.print_list();
myList.swap_values(9, 2);
std::cout << "Print list: n";
myList.print_list();

// Remove nodes from the list
myList.push_back(9);
myList.push_back(3);
myList.push_back(9);
myList.print_list();
myList.remove_nodes(5);
myList.remove_nodes(9);
myList.remove_nodes(4);
std::cout << "Print list: n";
myList.print_list();

// Reverse the list
myList.push_back(9);
myList.push_back(3);
myList.push_back(9);
myList.print_list();
myList.reverse();
std::cout << "Print list: n";
myList.print_list();

}









share|improve this question







New contributor




user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    0
    down vote

    favorite












    This code seems to work correctly. I would appreciate any comments on how to improve the code, e.g. readability, algorithms, const-correctness, memory, anything else I am forgetting?
    Also, for the function swap_values, would it make more sense to swap two nodes instead of just values of the nodes and why?



    SinglyLinkedList.hpp



    #pragma once

    #include <iostream>

    class SinglyLinkedList {
    private:
    struct ListNode {
    int value;
    std::shared_ptr<ListNode> next;
    ListNode(int val) : value(val), next(nullptr) {}
    };

    std::shared_ptr<ListNode> head;
    std::shared_ptr<ListNode> tail;

    std::shared_ptr<ListNode> find (int val) const;

    public:
    SinglyLinkedList();

    void print_list () const;
    void push_back (int val);
    void pop_back ();
    void push_front (int val);
    void pop_front ();
    size_t get_size () const;
    bool search (int val) const;
    void swap_values (int val1, int val2);
    void remove_nodes (int val);
    void reverse ();

    ~SinglyLinkedList();

    };


    SinglyLinkedList.cpp



    #include "SinglyLinkedList.hpp"


    SinglyLinkedList::SinglyLinkedList () : head (nullptr), tail (nullptr) {

    }

    void SinglyLinkedList::print_list () const {
    // O(n)
    if (head) {
    std::shared_ptr<ListNode> tempNode = head;
    while (tempNode) {
    std::cout << tempNode->value << " ";
    tempNode = tempNode->next;
    }
    std::cout << "n";
    } else {
    std::cout << "List is empty.n";
    }
    }

    void SinglyLinkedList::push_back(int val) {
    // O(n)
    std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
    if (head) {
    std::shared_ptr<ListNode> tempNode = head;
    while (tempNode != tail) {
    tempNode = tempNode->next;
    }
    tempNode->next = currNode;
    tail = currNode;
    } else {
    head = currNode;
    tail = currNode;
    }
    }

    void SinglyLinkedList::pop_back () {
    // O(n)
    if (!head) {
    std::cout << "List is empty.n";
    return;
    }
    if (head == tail) {
    head = nullptr;
    tail = nullptr;
    return;
    }
    std::shared_ptr<ListNode> currNode = head;
    while (currNode->next != tail) {
    currNode = currNode->next;
    }
    tail = currNode;
    currNode->next = nullptr;
    }

    void SinglyLinkedList::push_front (int val) {
    // O(1)
    std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
    currNode->next = head;
    head = currNode;
    }

    void SinglyLinkedList::pop_front () {
    // O(1)
    if (!head) {
    std::cout << "List is empty.n";
    return;
    }
    std::shared_ptr<ListNode> currNode = head;
    head = head->next;
    currNode->next = nullptr;
    }

    size_t SinglyLinkedList::get_size () const {
    // O(n)
    size_t listSize = 0;
    std::shared_ptr<ListNode> currNode = head;
    while (currNode) {
    ++listSize;
    currNode = currNode->next;
    }

    return listSize;
    }

    bool SinglyLinkedList::search (int val) const {
    // O(n)
    if (!head) {
    std::cout << "List is empty.n";
    return false;
    }
    std::shared_ptr<ListNode> currNode = head;
    while (currNode) {
    if (currNode->value == val) {
    //std::cout << "Value " << val << " is in the listn";
    return true;
    }
    currNode = currNode->next;
    }
    //std::cout << "Value " << val << " is not in the list.n";
    return false;
    }
    std::shared_ptr<SinglyLinkedList::ListNode> SinglyLinkedList::find (int val) const {
    // O(n)
    if (!head) {
    return nullptr;
    }
    std::shared_ptr<ListNode> currNode = head;
    while (currNode) {
    if (currNode->value == val) {
    return currNode;
    }
    currNode = currNode->next;
    }
    return nullptr;
    }

    void SinglyLinkedList::swap_values (int val1, int val2) {
    // swap is O(1), find is O(n)
    // Should I be swapping nodes instead of values?
    std::shared_ptr<ListNode> val1Node = find (val1);
    std::shared_ptr<ListNode> val2Node = find (val2);

    if (!val1Node) {
    std::cout << "Value " << val1 << " is not in the list.n";
    return;
    }
    if (!val2Node) {
    std::cout << "Value " << val2 << " is not in the list.n";
    return;
    }

    int tempNodeVal = val1Node->value;
    val1Node->value = val2Node->value;
    val2Node->value = tempNodeVal;
    }

    void SinglyLinkedList::remove_nodes (int val) {
    if (!head) {
    std::cout << "List is empty.n";
    return;
    }
    std::shared_ptr<ListNode> prevNode = nullptr;
    std::shared_ptr<ListNode> currNode = head;
    while (currNode) {
    if (currNode->value == val) {
    // val found - remove
    if (!prevNode) {
    // delete head node
    if (head == tail) {
    head = nullptr;
    tail = nullptr;
    return;
    }
    head = head->next;
    prevNode = currNode;
    currNode = currNode->next;
    prevNode->next = nullptr;
    prevNode = nullptr;
    } else if (currNode == tail) {
    // delete tail node
    tail = prevNode;
    prevNode->next = nullptr;
    currNode->next = nullptr;
    } else {
    prevNode->next = currNode->next;
    currNode->next = nullptr;
    currNode = prevNode->next;
    }
    } else {
    // val not found
    prevNode = currNode;
    currNode = currNode->next;
    }
    }
    }

    void SinglyLinkedList::reverse () {
    // O(n)
    if (!head || head == tail) {
    return;
    }
    std::shared_ptr<ListNode> currNode = head;
    std::shared_ptr<ListNode> prevNode = nullptr;
    std::shared_ptr<ListNode> nextNode = nullptr;
    head = nullptr;
    tail = head;
    while (currNode) {
    nextNode = currNode->next;
    currNode->next = prevNode;
    prevNode = currNode;
    currNode = nextNode;
    }
    head = prevNode;
    }

    SinglyLinkedList::~SinglyLinkedList () {

    }


    main.cpp



    #include "SinglyLinkedList.hpp"

    int main() {

    // List init
    SinglyLinkedList myList;

    std::cout << "Print list: n";
    myList.print_list();
    std::cout << "List size: " << myList.get_size() << "n";

    // Add nodes to the back of the list
    myList.push_back(2);
    myList.push_back(4);
    myList.push_back(3);
    myList.push_back(1);
    std::cout << "Print list: n";
    myList.print_list();
    std::cout << "List size: " << myList.get_size() << "n";

    // Add nodes to the front of the list
    myList.push_front(5);
    myList.push_front(7);
    myList.push_front(6);
    std::cout << "Print list: n";
    myList.print_list();
    std::cout << "List size: " << myList.get_size() << "n";

    // Pop nodes from the front of the list
    myList.pop_front();
    myList.pop_front();
    std::cout << "Print list: n";
    myList.print_list();
    std::cout << "List size: " << myList.get_size() << "n";

    // Pop nodes from the back of the list
    myList.pop_back();
    myList.pop_back();
    std::cout << "Print list: n";
    myList.print_list();
    std::cout << "List size: " << myList.get_size() << "n";

    // Check if node with specific velue is in the list
    int valToSearch = 3;
    bool foundVal = myList.search(valToSearch);
    if (foundVal) {
    std::cout << valToSearch << " is in the list.n";
    } else {
    std::cout << valToSearch << " is not in the list.n";
    }

    // Swap the values of two nodes
    myList.push_back(7);
    myList.push_back(8);
    myList.push_back(9);
    myList.print_list();
    myList.swap_values(9, 2);
    std::cout << "Print list: n";
    myList.print_list();

    // Remove nodes from the list
    myList.push_back(9);
    myList.push_back(3);
    myList.push_back(9);
    myList.print_list();
    myList.remove_nodes(5);
    myList.remove_nodes(9);
    myList.remove_nodes(4);
    std::cout << "Print list: n";
    myList.print_list();

    // Reverse the list
    myList.push_back(9);
    myList.push_back(3);
    myList.push_back(9);
    myList.print_list();
    myList.reverse();
    std::cout << "Print list: n";
    myList.print_list();

    }









    share|improve this question







    New contributor




    user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      This code seems to work correctly. I would appreciate any comments on how to improve the code, e.g. readability, algorithms, const-correctness, memory, anything else I am forgetting?
      Also, for the function swap_values, would it make more sense to swap two nodes instead of just values of the nodes and why?



      SinglyLinkedList.hpp



      #pragma once

      #include <iostream>

      class SinglyLinkedList {
      private:
      struct ListNode {
      int value;
      std::shared_ptr<ListNode> next;
      ListNode(int val) : value(val), next(nullptr) {}
      };

      std::shared_ptr<ListNode> head;
      std::shared_ptr<ListNode> tail;

      std::shared_ptr<ListNode> find (int val) const;

      public:
      SinglyLinkedList();

      void print_list () const;
      void push_back (int val);
      void pop_back ();
      void push_front (int val);
      void pop_front ();
      size_t get_size () const;
      bool search (int val) const;
      void swap_values (int val1, int val2);
      void remove_nodes (int val);
      void reverse ();

      ~SinglyLinkedList();

      };


      SinglyLinkedList.cpp



      #include "SinglyLinkedList.hpp"


      SinglyLinkedList::SinglyLinkedList () : head (nullptr), tail (nullptr) {

      }

      void SinglyLinkedList::print_list () const {
      // O(n)
      if (head) {
      std::shared_ptr<ListNode> tempNode = head;
      while (tempNode) {
      std::cout << tempNode->value << " ";
      tempNode = tempNode->next;
      }
      std::cout << "n";
      } else {
      std::cout << "List is empty.n";
      }
      }

      void SinglyLinkedList::push_back(int val) {
      // O(n)
      std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
      if (head) {
      std::shared_ptr<ListNode> tempNode = head;
      while (tempNode != tail) {
      tempNode = tempNode->next;
      }
      tempNode->next = currNode;
      tail = currNode;
      } else {
      head = currNode;
      tail = currNode;
      }
      }

      void SinglyLinkedList::pop_back () {
      // O(n)
      if (!head) {
      std::cout << "List is empty.n";
      return;
      }
      if (head == tail) {
      head = nullptr;
      tail = nullptr;
      return;
      }
      std::shared_ptr<ListNode> currNode = head;
      while (currNode->next != tail) {
      currNode = currNode->next;
      }
      tail = currNode;
      currNode->next = nullptr;
      }

      void SinglyLinkedList::push_front (int val) {
      // O(1)
      std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
      currNode->next = head;
      head = currNode;
      }

      void SinglyLinkedList::pop_front () {
      // O(1)
      if (!head) {
      std::cout << "List is empty.n";
      return;
      }
      std::shared_ptr<ListNode> currNode = head;
      head = head->next;
      currNode->next = nullptr;
      }

      size_t SinglyLinkedList::get_size () const {
      // O(n)
      size_t listSize = 0;
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      ++listSize;
      currNode = currNode->next;
      }

      return listSize;
      }

      bool SinglyLinkedList::search (int val) const {
      // O(n)
      if (!head) {
      std::cout << "List is empty.n";
      return false;
      }
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      if (currNode->value == val) {
      //std::cout << "Value " << val << " is in the listn";
      return true;
      }
      currNode = currNode->next;
      }
      //std::cout << "Value " << val << " is not in the list.n";
      return false;
      }
      std::shared_ptr<SinglyLinkedList::ListNode> SinglyLinkedList::find (int val) const {
      // O(n)
      if (!head) {
      return nullptr;
      }
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      if (currNode->value == val) {
      return currNode;
      }
      currNode = currNode->next;
      }
      return nullptr;
      }

      void SinglyLinkedList::swap_values (int val1, int val2) {
      // swap is O(1), find is O(n)
      // Should I be swapping nodes instead of values?
      std::shared_ptr<ListNode> val1Node = find (val1);
      std::shared_ptr<ListNode> val2Node = find (val2);

      if (!val1Node) {
      std::cout << "Value " << val1 << " is not in the list.n";
      return;
      }
      if (!val2Node) {
      std::cout << "Value " << val2 << " is not in the list.n";
      return;
      }

      int tempNodeVal = val1Node->value;
      val1Node->value = val2Node->value;
      val2Node->value = tempNodeVal;
      }

      void SinglyLinkedList::remove_nodes (int val) {
      if (!head) {
      std::cout << "List is empty.n";
      return;
      }
      std::shared_ptr<ListNode> prevNode = nullptr;
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      if (currNode->value == val) {
      // val found - remove
      if (!prevNode) {
      // delete head node
      if (head == tail) {
      head = nullptr;
      tail = nullptr;
      return;
      }
      head = head->next;
      prevNode = currNode;
      currNode = currNode->next;
      prevNode->next = nullptr;
      prevNode = nullptr;
      } else if (currNode == tail) {
      // delete tail node
      tail = prevNode;
      prevNode->next = nullptr;
      currNode->next = nullptr;
      } else {
      prevNode->next = currNode->next;
      currNode->next = nullptr;
      currNode = prevNode->next;
      }
      } else {
      // val not found
      prevNode = currNode;
      currNode = currNode->next;
      }
      }
      }

      void SinglyLinkedList::reverse () {
      // O(n)
      if (!head || head == tail) {
      return;
      }
      std::shared_ptr<ListNode> currNode = head;
      std::shared_ptr<ListNode> prevNode = nullptr;
      std::shared_ptr<ListNode> nextNode = nullptr;
      head = nullptr;
      tail = head;
      while (currNode) {
      nextNode = currNode->next;
      currNode->next = prevNode;
      prevNode = currNode;
      currNode = nextNode;
      }
      head = prevNode;
      }

      SinglyLinkedList::~SinglyLinkedList () {

      }


      main.cpp



      #include "SinglyLinkedList.hpp"

      int main() {

      // List init
      SinglyLinkedList myList;

      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Add nodes to the back of the list
      myList.push_back(2);
      myList.push_back(4);
      myList.push_back(3);
      myList.push_back(1);
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Add nodes to the front of the list
      myList.push_front(5);
      myList.push_front(7);
      myList.push_front(6);
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Pop nodes from the front of the list
      myList.pop_front();
      myList.pop_front();
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Pop nodes from the back of the list
      myList.pop_back();
      myList.pop_back();
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Check if node with specific velue is in the list
      int valToSearch = 3;
      bool foundVal = myList.search(valToSearch);
      if (foundVal) {
      std::cout << valToSearch << " is in the list.n";
      } else {
      std::cout << valToSearch << " is not in the list.n";
      }

      // Swap the values of two nodes
      myList.push_back(7);
      myList.push_back(8);
      myList.push_back(9);
      myList.print_list();
      myList.swap_values(9, 2);
      std::cout << "Print list: n";
      myList.print_list();

      // Remove nodes from the list
      myList.push_back(9);
      myList.push_back(3);
      myList.push_back(9);
      myList.print_list();
      myList.remove_nodes(5);
      myList.remove_nodes(9);
      myList.remove_nodes(4);
      std::cout << "Print list: n";
      myList.print_list();

      // Reverse the list
      myList.push_back(9);
      myList.push_back(3);
      myList.push_back(9);
      myList.print_list();
      myList.reverse();
      std::cout << "Print list: n";
      myList.print_list();

      }









      share|improve this question







      New contributor




      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      This code seems to work correctly. I would appreciate any comments on how to improve the code, e.g. readability, algorithms, const-correctness, memory, anything else I am forgetting?
      Also, for the function swap_values, would it make more sense to swap two nodes instead of just values of the nodes and why?



      SinglyLinkedList.hpp



      #pragma once

      #include <iostream>

      class SinglyLinkedList {
      private:
      struct ListNode {
      int value;
      std::shared_ptr<ListNode> next;
      ListNode(int val) : value(val), next(nullptr) {}
      };

      std::shared_ptr<ListNode> head;
      std::shared_ptr<ListNode> tail;

      std::shared_ptr<ListNode> find (int val) const;

      public:
      SinglyLinkedList();

      void print_list () const;
      void push_back (int val);
      void pop_back ();
      void push_front (int val);
      void pop_front ();
      size_t get_size () const;
      bool search (int val) const;
      void swap_values (int val1, int val2);
      void remove_nodes (int val);
      void reverse ();

      ~SinglyLinkedList();

      };


      SinglyLinkedList.cpp



      #include "SinglyLinkedList.hpp"


      SinglyLinkedList::SinglyLinkedList () : head (nullptr), tail (nullptr) {

      }

      void SinglyLinkedList::print_list () const {
      // O(n)
      if (head) {
      std::shared_ptr<ListNode> tempNode = head;
      while (tempNode) {
      std::cout << tempNode->value << " ";
      tempNode = tempNode->next;
      }
      std::cout << "n";
      } else {
      std::cout << "List is empty.n";
      }
      }

      void SinglyLinkedList::push_back(int val) {
      // O(n)
      std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
      if (head) {
      std::shared_ptr<ListNode> tempNode = head;
      while (tempNode != tail) {
      tempNode = tempNode->next;
      }
      tempNode->next = currNode;
      tail = currNode;
      } else {
      head = currNode;
      tail = currNode;
      }
      }

      void SinglyLinkedList::pop_back () {
      // O(n)
      if (!head) {
      std::cout << "List is empty.n";
      return;
      }
      if (head == tail) {
      head = nullptr;
      tail = nullptr;
      return;
      }
      std::shared_ptr<ListNode> currNode = head;
      while (currNode->next != tail) {
      currNode = currNode->next;
      }
      tail = currNode;
      currNode->next = nullptr;
      }

      void SinglyLinkedList::push_front (int val) {
      // O(1)
      std::shared_ptr<ListNode> currNode = std::make_shared<ListNode>(val);
      currNode->next = head;
      head = currNode;
      }

      void SinglyLinkedList::pop_front () {
      // O(1)
      if (!head) {
      std::cout << "List is empty.n";
      return;
      }
      std::shared_ptr<ListNode> currNode = head;
      head = head->next;
      currNode->next = nullptr;
      }

      size_t SinglyLinkedList::get_size () const {
      // O(n)
      size_t listSize = 0;
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      ++listSize;
      currNode = currNode->next;
      }

      return listSize;
      }

      bool SinglyLinkedList::search (int val) const {
      // O(n)
      if (!head) {
      std::cout << "List is empty.n";
      return false;
      }
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      if (currNode->value == val) {
      //std::cout << "Value " << val << " is in the listn";
      return true;
      }
      currNode = currNode->next;
      }
      //std::cout << "Value " << val << " is not in the list.n";
      return false;
      }
      std::shared_ptr<SinglyLinkedList::ListNode> SinglyLinkedList::find (int val) const {
      // O(n)
      if (!head) {
      return nullptr;
      }
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      if (currNode->value == val) {
      return currNode;
      }
      currNode = currNode->next;
      }
      return nullptr;
      }

      void SinglyLinkedList::swap_values (int val1, int val2) {
      // swap is O(1), find is O(n)
      // Should I be swapping nodes instead of values?
      std::shared_ptr<ListNode> val1Node = find (val1);
      std::shared_ptr<ListNode> val2Node = find (val2);

      if (!val1Node) {
      std::cout << "Value " << val1 << " is not in the list.n";
      return;
      }
      if (!val2Node) {
      std::cout << "Value " << val2 << " is not in the list.n";
      return;
      }

      int tempNodeVal = val1Node->value;
      val1Node->value = val2Node->value;
      val2Node->value = tempNodeVal;
      }

      void SinglyLinkedList::remove_nodes (int val) {
      if (!head) {
      std::cout << "List is empty.n";
      return;
      }
      std::shared_ptr<ListNode> prevNode = nullptr;
      std::shared_ptr<ListNode> currNode = head;
      while (currNode) {
      if (currNode->value == val) {
      // val found - remove
      if (!prevNode) {
      // delete head node
      if (head == tail) {
      head = nullptr;
      tail = nullptr;
      return;
      }
      head = head->next;
      prevNode = currNode;
      currNode = currNode->next;
      prevNode->next = nullptr;
      prevNode = nullptr;
      } else if (currNode == tail) {
      // delete tail node
      tail = prevNode;
      prevNode->next = nullptr;
      currNode->next = nullptr;
      } else {
      prevNode->next = currNode->next;
      currNode->next = nullptr;
      currNode = prevNode->next;
      }
      } else {
      // val not found
      prevNode = currNode;
      currNode = currNode->next;
      }
      }
      }

      void SinglyLinkedList::reverse () {
      // O(n)
      if (!head || head == tail) {
      return;
      }
      std::shared_ptr<ListNode> currNode = head;
      std::shared_ptr<ListNode> prevNode = nullptr;
      std::shared_ptr<ListNode> nextNode = nullptr;
      head = nullptr;
      tail = head;
      while (currNode) {
      nextNode = currNode->next;
      currNode->next = prevNode;
      prevNode = currNode;
      currNode = nextNode;
      }
      head = prevNode;
      }

      SinglyLinkedList::~SinglyLinkedList () {

      }


      main.cpp



      #include "SinglyLinkedList.hpp"

      int main() {

      // List init
      SinglyLinkedList myList;

      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Add nodes to the back of the list
      myList.push_back(2);
      myList.push_back(4);
      myList.push_back(3);
      myList.push_back(1);
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Add nodes to the front of the list
      myList.push_front(5);
      myList.push_front(7);
      myList.push_front(6);
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Pop nodes from the front of the list
      myList.pop_front();
      myList.pop_front();
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Pop nodes from the back of the list
      myList.pop_back();
      myList.pop_back();
      std::cout << "Print list: n";
      myList.print_list();
      std::cout << "List size: " << myList.get_size() << "n";

      // Check if node with specific velue is in the list
      int valToSearch = 3;
      bool foundVal = myList.search(valToSearch);
      if (foundVal) {
      std::cout << valToSearch << " is in the list.n";
      } else {
      std::cout << valToSearch << " is not in the list.n";
      }

      // Swap the values of two nodes
      myList.push_back(7);
      myList.push_back(8);
      myList.push_back(9);
      myList.print_list();
      myList.swap_values(9, 2);
      std::cout << "Print list: n";
      myList.print_list();

      // Remove nodes from the list
      myList.push_back(9);
      myList.push_back(3);
      myList.push_back(9);
      myList.print_list();
      myList.remove_nodes(5);
      myList.remove_nodes(9);
      myList.remove_nodes(4);
      std::cout << "Print list: n";
      myList.print_list();

      // Reverse the list
      myList.push_back(9);
      myList.push_back(3);
      myList.push_back(9);
      myList.print_list();
      myList.reverse();
      std::cout << "Print list: n";
      myList.print_list();

      }






      c++ algorithm c++11 linked-list






      share|improve this question







      New contributor




      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 15 mins ago









      user_185051

      212




      212




      New contributor




      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      user_185051 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



























          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          user_185051 is a new contributor. Be nice, and check out our Code of Conduct.










           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208260%2fsingly-linked-list-data-structure-implementation%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          user_185051 is a new contributor. Be nice, and check out our Code of Conduct.










           

          draft saved


          draft discarded


















          user_185051 is a new contributor. Be nice, and check out our Code of Conduct.













          user_185051 is a new contributor. Be nice, and check out our Code of Conduct.












          user_185051 is a new contributor. Be nice, and check out our Code of Conduct.















           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208260%2fsingly-linked-list-data-structure-implementation%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          Refactoring coordinates for Minecraft Pi buildings written in Python