Skip to content

Instantly share code, notes, and snippets.

@chrisengelsma
Last active October 7, 2019 17:00
Show Gist options
  • Save chrisengelsma/7d29883148f7421d58b7965a0f895a75 to your computer and use it in GitHub Desktop.
Save chrisengelsma/7d29883148f7421d58b7965a0f895a75 to your computer and use it in GitHub Desktop.
C++17 Linked List Implementation
/**
* @class LinkedList
* @brief A simple linked list.
*
* A linked list is a data structure represented by a series of nodes wherein
* each node maintains a record of its stored value and a pointer to another
* node.
*
* This implementation is intended to provide very basic functionality,
* including insertion, deletion, and size.
*
* @author Chris Engelsma <chris.engelsma@gmail.com>
* @date Oct 7, 2019
*/
#pragma once
#include <iostream>
#include <sstream>
template<typename T>
struct Node
{
T data;
Node* next;
};
template<typename T>
class LinkedList
{
public:
// The head node.
Node<T>* m_head{nullptr};
/**
* @brief Constructs an empty linked list.
*/
constexpr LinkedList() = default;
/**
* @brief Destructs this linked list.
*/
~LinkedList();
/**
* @brief Returns this linked list as a space-delimited std::string.
* @return a std::string representation of this list.
*/
[[nodiscard]] std::string toString() const;
/**
* @brief Inserts a value at the beginning of this list.
* @param value a node value to insert.
*/
template<typename K>
constexpr void insertFirst(const K& value);
void insertFirst(const T& value);
/**
* @brief Inserts a value at the end of this list.
* @param value a node value to insert.
*/
template<typename K>
constexpr void insertLast(const K& value);
void insertLast(const T& value);
/**
* @brief Removes the first value from this list.
*/
void removeFirst();
/**
* @brief Determines if this linked list is empty.
* @return true, if empty; false, otherwise.
*/
[[nodiscard]] bool isEmpty() const { return m_head == nullptr; };
/**
* @brief Removes the last value from this list.
*/
void removeLast();
/**
* @brief Gets the number of nodes in this list.
* @return the number of nodes in this list.
*/
[[nodiscard]] size_t size() const;
friend std::ostream& operator<<(std::ostream& stream, const LinkedList& list)
{
stream << list.toString();
return stream;
}
};
using LinkedListf = LinkedList<float>;
using LinkedListd = LinkedList<double>;
using LinkedListi = LinkedList<int32_t>;
using LinkedListui = LinkedList<uint32_t>;
#include "LinkedList.inl"
#include "LinkedList.h"
template<typename T>
LinkedList<T>::~LinkedList()
{
if (m_head != nullptr)
{
auto node = m_head->next;
while (node != nullptr)
{
auto next = node->next;
delete node;
node = next;
}
m_head = nullptr;
}
}
template<typename T>
template<typename K>
constexpr void LinkedList<T>::insertFirst(const K& value)
{
(*this)->insertFirst(static_cast<T>(value));
}
template<typename T>
template<typename K>
constexpr void LinkedList<T>::insertLast(const K& value)
{
(*this)->insertLast(static_cast<T>(value));
}
template<typename T>
void LinkedList<T>::insertFirst(const T& value)
{
auto node = new Node<T>();
node->data = value;
if (m_head == nullptr)
{
m_head = node;
m_head->next = nullptr;
}
else
{
auto temp = m_head;
m_head = node;
m_head->next = temp;
}
}
template<typename T>
void LinkedList<T>::insertLast(const T& value)
{
auto node = new Node<T>();
node->data = value;
node->next = nullptr;
if (m_head == nullptr)
{
m_head = node;
return;
}
auto temp = m_head;
while (temp->next != nullptr)
{
temp = temp->next;
}
node->next = nullptr;
temp->next = node;
}
template<typename T>
void LinkedList<T>::removeFirst()
{
if (m_head == nullptr)
{
return;
}
m_head = m_head->next;
}
template<typename T>
void LinkedList<T>::removeLast()
{
if (m_head == nullptr)
{
return;
}
if (m_head->next == nullptr)
{
delete m_head;
return;
}
auto node = m_head;
while (node->next->next != nullptr)
{
node = node->next;
}
delete node->next;
node->next = nullptr;
}
template<typename T>
size_t LinkedList<T>::size() const
{
auto node = m_head;
size_t counter = 0;
while (node != nullptr)
{
counter++;
node = node->next;
}
return counter;
}
template<typename T>
std::string LinkedList<T>::toString() const
{
std::stringstream stream;
auto node = m_head;
if (node != nullptr)
{
while (node != nullptr)
{
stream << node->data << " -> ";
node = node->next;
}
}
stream << "NULL";
return stream.str();
}
#include "LinkedList.h"
#include <ctime>
#include <iostream>
#include <cstdlib>
/**
* Demos LinkedList by randomly inserting 10 integers.
*/
int main()
{
auto list = new LinkedListi();
srand(time(nullptr));
int min = 0; // Min integer
int max = 100; // Max integer
int n = 10; // Insert 10 random integers.
int i = 0;
do
{
int value = rand() % max + min;
std::cout << "Value to insert: " << value << std::endl;
list->insertLast(value);
std::cout << *list << std::endl;
i++;
} while (i<n);
do
{
std::cout << "Removing first value" << std::endl;
list->removeFirst();
std::cout << *list << std::endl;
} while (list->size() > 0);
delete list; list = nullptr;
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment