I implemented a single-linked and double-linked lists (like stack and deque).
- Using double sentinels for double-linked (front_, back_) is very convenient and easy to understand code.
- The methods present in the classes are quite sufficient for my tasks.
- I dont want to share these classes. They are for personal use only. So I don't need to adapt them to the standard library, concepts, put in namespace, change #ifndef guard, and other
- The code style corresponds to Google's code style (https://google.github.io/styleguide/cppguide.html)
- And many thanks to Loki Astari, for all advices
I would like to get some advicesreceive your feedback on speeding upimproving the work of these classes, if possiblecode or maybe some comments.
I'm learning C++ for the third month. I will be glad to receive criticism. (sorry for google translate)
#ifndef DLL_HPP
#define DLL_HPP
#include <iostream>
////////////////////////////////////
// DLListDLLNode declaration
//////////////////////////////////
template <typename DataType>
class DLList {
private:
////////////////////////////////////
// DLLNode declaration
//////////////////////////////////
class DLLNode {
public:
DataType& GetData();
private:
friend DLList;
DLLNode(const DLLNode&) = delete;
DLLNode(DLLNode&&) = delete;
template <class DataType>
struct DLLNode {
public:
DLLNode(const DLLNode<DataType>&); = delete;
DLLNode(DLLNode<DataType>&&) = delete;
DataType data;
DLLNode* prev;
DLLNode* next;DLLNode();
}~DLLNode();
typedef DLLNodeDataType Node;data;
typedef Node*DLLNode* NodePtr;
prev{ nullptr };
typedef unsigned longDLLNode* longnext{ intnullptr size_t;};
};
NodePtr front_{ nullptr };////////////////////////////////////
NodePtr back_{// nullptrDLList };declaration
size_t size_{////////////////////////////////// 0 };
template <class DataType>
class DLList {
public:
typedef DLLNode<DataType> Node;
typedef DLLNode<DataType>* NodePtr;
DLList(const DLList&) = delete;
DLList(DLList&&) = delete;
DLList();
~DLList();
void Clear();
void PushBack(DataType&&const DataType& data);
void PushFront(DataType&&const DataType& data);
void PopBack();
void PopFront();
DataType&DLLNode<DataType>* Back();
DataType&DLLNode<DataType>* Front();
template <typename<class OperationFnc>
void FromBack(OperationFnc& operation_fnc);
template <typename<class OperationFnc>
void FromFront(OperationFnc& operation_fnc);
bool IsEmpty() const;;
size_tunsigned long long int Size();
const; void Print();
private:
templateNodePtr <typenamefront_{ PrintFnc>nullptr };
voidNodePtr Print(constback_{ PrintFnc&nullptr print_fnc)};
const; unsigned long long int size_{ 0 };
};
////////////////////////////////////
// DLLNode defenition
//////////////////////////////////
template<typename DataType>
inline DataType& DLList<DataType>::DLLNode::GetData() {
return data;
}
template<typenametemplate<class DataType>
inline DLList<DataType>::DLLNodeDLLNode<DataType>::DLLNode() :
next{ nullptr },
prev{ nullptr }
{
// Default constructor
}
template<class DataType>
inline DLLNode<DataType>::~DLLNode() {
data.~DataType();
}
////////////////////////////////////
// DLList defenition
//////////////////////////////////
template<typenametemplate<class DataType>
inline DLList<DataType>::DLList() :
front_{ new Node() },
back_{ new Node() },
size_{ 0 }
{
back_->prev = front_;
back_->data = DataType();
front_->next = back_;
front_->data = DataType();
}
template<typenametemplate<class DataType>
inline DLList<DataType>::~DLList() {
Clear();
delete back_;
delete front_;
}
template<typenametemplate<class DataType>
inline void DLList<DataType>::Clear() {
if (IsEmpty()) {
return;
}
NodePtr index = front_->next;
NodePtr current;
while (index != back_) {
current = index;
index = index->next;
delete current;
}
front_->next = back_;
back_->prev = front_;
size_ = 0;
}
template<typenametemplate<class DataType>
inline void DLList<DataType>::PushBack(DataType&&const DataType& data) {
NodePtr newbie = new Node();
newbie->data = data;DataType(data);
NodePtr back_node = back_->prev;
back_node->next = newbie;
newbie->prev = back_node;
newbie->next = back_;
back_->prev = newbie;
++size_;
}
template<typenametemplate<class DataType>
inline void DLList<DataType>::PushFront(DataType&&const DataType& data) {
NodePtr newbie = new Node();
newbie->data = data;DataType(data);
NodePtr front_node = front_->next;
front_node->prev = newbie;
newbie->next = front_node;
newbie->prev = front_;
front_->next = newbie;
++size_;
}
template<typenametemplate<class DataType>
inline void DLList<DataType>::PopBack() {
if (IsEmpty()) {
return;
}
NodePtr back_node = back_->prev;
back_->prev = back_node->prev;
back_node->prev->next = back_;
delete back_node;
--size_;
}
template<typenametemplate<class DataType>
inline void DLList<DataType>::PopFront() {
if (IsEmpty()) {
return;
}
NodePtr front_node = front_->next;
front_->next = front_node->next;
front_node->next->prev = front_;
delete front_node;
--size_;
}
template<typenametemplate<class DataType>
inline DataType&DLLNode<DataType>* DLList<DataType>::Back() {
return IsEmpty() ? back_->data : back_->prev->data;>prev;
}
template<typenametemplate<class DataType>
inline DataType&DLLNode<DataType>* DLList<DataType>::Front() {
return IsEmpty() ? front_->data : front_->next->data;>next;
}
template<typenametemplate<class DataType>
template<typenametemplate<class OperationFnc>
inline void DLList<DataType>::FromBack(OperationFnc& operation_fnc) {
if (IsEmpty()) {
return;
}
NodePtr index = back_->prev;
NodePtr current;
while (index != front_) {
current = index;
index = index->prev;
operation_fnc(current);
}
}
template<typenametemplate<class DataType>
template<typenametemplate<class OperationFnc>
inline void DLList<DataType>::FromFront(OperationFnc& operation_fnc) {
if (IsEmpty()) {
return;
}
NodePtr index = front_->next;
NodePtr current;
while (index != back_) {
current = index;
index = index->next;
operation_fnc(current);
}
}
template<typenametemplate<class DataType>
inline bool DLList<DataType>::IsEmpty() const {
return size_ == 0;
}
template<typenametemplate<class DataType>
typenameinline DLList<DataType>::size_tunsigned long long int DLList<DataType>::Size() const {
return size_;
}
template<typenametemplate<class DataType>
template<typename PrintFnc>
inline void DLList<DataType>::Print(const PrintFnc& print_fnc) const {
if (IsEmpty()) {
print_fnc(std::cout << "List is empty");empty";
return;
}
NodePtr index = front_->next;
while (index != back_) {
print_fnc("[");
std::cout << "[" << print_fnc(index->data);
<< print_fnc("]");"]";
if (index->next != back_) {
print_fnc("<=>");std::cout << "<=>";
}
index = index->next;
}
}
#endif
#ifndef SLL_HPP
#define SLL_HPP
#include <iostream>
////////////////////////////////////
// SLListSLLNode declaration
//////////////////////////////////
template <typename<class DataType>
classstruct SLListSLLNode {
privatepublic:
SLLNode(const SLLNode<DataType>&) = delete;
SLLNode(SLLNode<DataType>&&) = delete;
SLLNode();
~SLLNode();
DataType data;
SLLNode* prev{ nullptr };
};
////////////////////////////////////
// SLLNodeSLList declaration
//////////////////////////////////
template <class structDataType>
class SLLNodeSLList {
public:
DataType& GetData();
private:
friend SLList;
SLLNode(const SLLNode&) = delete;
SLLNode(SLLNode&&) = delete;
SLLNode();
DataType data;
SLLNode* prev;
};
typedef SLLNodeSLLNode<DataType> Node;
typedef Node*SLLNode<DataType>* NodePtr;
typedef unsigned long long int size_t;
NodePtr back_{ nullptr };
size_t size_{ 0 };
public:
SLList(const SLList&) = delete;
SLList(SLList&&) = delete;
SLList();
~SLList();
void Clear();
void PushBack(DataType&&const DataType& data);
void PopBack();
DataType&SLLNode<DataType>* Back();
template <typename<class OperationFnc>
void FromBack(OperationFnc& operation_fnc);
bool IsEmpty() const;;
size_tunsigned long long int Size();
const; void Print();
private:
templateNodePtr <typenameback_{ PrintFnc>nullptr };
voidunsigned Print(constlong PrintFnc&long print_fnc)int const;size_{ 0 };
};
////////////////////////////////////
// SLLNode defenition
//////////////////////////////////
template<typename DataType>
inline DataType& SLList<DataType>::SLLNode::GetData(){
return data;
}
template<typenametemplate<class DataType>
inline SLList<DataType>::SLLNodeSLLNode<DataType>::SLLNode() :
prev{ nullptr }
{
// Default constructor
}
template<class DataType>
inline SLLNode<DataType>::~SLLNode() {
data.~DataType();
}
////////////////////////////////////
// SLList defenition
//////////////////////////////////
template<typenametemplate<class DataType>
inline SLList<DataType>::SLList() :
back_{ new Node() },
size_{ 0 }
{
back_->data = DataType();
}
template<typenametemplate<class DataType>
inline SLList<DataType>::~SLList() {
Clear();
delete back_;
}
template<typenametemplate<class DataType>
inline void SLList<DataType>::Clear() {
if (IsEmpty()) {
return;
}
NodePtr index = back_->prev;
NodePtr current;
while (index != nullptr) {
current = index;
index = index->prev;
delete current;
}
back_->prev = nullptr;
size_ = 0;
}
template<typenametemplate<class DataType>
inline void SLList<DataType>::PushBack(DataType&&const DataType& data) {
NodePtr newbie = new Node();
newbie->data = data;DataType(data);
NodePtr back_node = back_->prev;
newbie->prev = back_node;
back_->prev = newbie;
++size_;
}
template<typenametemplate<class DataType>
inline void SLList<DataType>::PopBack() {
if (IsEmpty()) {
return;
}
NodePtr back_node = back_->prev;
back_->prev = back_node->prev;
delete back_node;
--size_;
}
template<typenametemplate<class DataType>
inline DataType&SLLNode<DataType>* SLList<DataType>::Back() {
return IsEmpty() ? back_->data : back_->prev->data;>prev;
}
template<typenametemplate<class DataType>
template<typenametemplate<class OperationFnc>
inline void SLList<DataType>::FromBack(OperationFnc& operation_fnc) {
if (IsEmpty()) {
return;
}
NodePtr index = back_->prev;
NodePtr current;
while (index != nullptr) {
current = index;
index = index->prev;
operation_fnc(current);
}
}
template<typenametemplate<class DataType>
inline bool SLList<DataType>::IsEmpty() const {
return size_ == 0;
}
template<typenametemplate<class DataType>
typenameinline SLList<DataType>::size_tunsigned long long int SLList<DataType>::Size() const {
return size_;
}
template<typenametemplate<class DataType>
template<typename PrintFnc>
inline void SLList<DataType>::Print(const PrintFnc& print_fnc) const {
if (IsEmpty()) {
print_fnc(std::cout << "List is empty");empty";
return;
}
NodePtr index = back_->prev;
while (index != nullptr) {
print_fnc("[");
std::cout << "[" << print_fnc(index->data);
<< print_fnc("]");"]";
if (index->prev != nullptr) {
print_fnc(std::cout << "<-");";
}
index = index->prev;
}
}
#endif