This is a follow-up to the previous question located at : Implementation of the linked list data structure in c++. I've tried to improve the design of the previous code by fixing some indexes that could go out of range and cause the de-referencing of a nullptr, and minor changes for compactness and elegance. However I'm not sure about the final result, (in all honesty I'm satisfied because this is my second week working with c++), that's why I'm asking for a feedback ! There's always room for improvement, thanks in advance and have a good day!
#ifndef NYO_UTIL_LINKEDLIST_H
#define NYO_UTIL_LINKEDLIST_H
#include <memory>
#include <iostream>
template <typename T> using ptr = std::shared_ptr<T>;
namespace Nyo{
namespace Util{
template <typename V>
class LinkedList
{
private:
class Node
{
private:
V data;
ptr<Node> next;
public:
Node(const V& _data) : next{}, data{_data} {}
ptr<Node>& getNext(){
return this->next;
}
V getData(){
return this->data;
}
};
ptr<Node> head;
ptr<Node> tail;
size_t _size;
public:
LinkedList() : head{}, tail {}, _size{} {}
void add(const V& _data){
auto _tmp = std::make_shared<Node>(_data);
if(isEmpty()){
head = (_tmp);
tail = (_tmp);
} else {
tail->getNext() = (_tmp);
tail = (_tmp);
}
_size++;
}
bool isEmpty(){
return (head==nullptr);
}
V operator[](int index){
if(index < 0 || isEmpty() || index > size()-1){ return {};}
else {
int _c {};
ptr<Node> tmp = (head);
while(tmp!=nullptr){
if(_c == index){
break;
}
tmp = (tmp->getNext());
_c++;
}
return tmp->getData();
}
}
void pushFront(const V& _data){
auto _tmp = std::make_shared<Node>(_data);
if(isEmpty()){
_tmp->getNext() = (head);
head = (_tmp);
tail = (_tmp);
} else {
_tmp->getNext() = (head);
head = (_tmp);
}
_size++;
}
template <typename V>
void insertAt(int index, const V& _data){
auto _tmp = std::make_shared<Node>(_data);
std::shared_ptr<Node> _curr;
std::shared_ptr<Node> _afterIndex;
if(index<0 || index > size()){std::cerr << "__INDEX_OUT_OF_RANGE__" << std::endl;}
else if (index==0) {
pushFront(_data);
}
else {
int _c {};
ptr<Node> tmp = (head);
while(tmp!=nullptr){
if(_c == index-1){
_curr = (tmp);
_afterIndex = (_curr->getNext());
break;
}
tmp = (tmp->getNext());
_c++;
}
_curr->getNext() = (_tmp);
_tmp->getNext() = (_afterIndex);
_size++;
}
}
bool find(const V& data){
bool _isIn;
for(ptr<Node> tmp {head}; tmp; tmp = tmp->getNext()){
if(tmp->getData() == data) {
_isIn = true;
break;
}
else _isIn = false;
}
return _isIn;
}
void display(){
ptr<Node> tmp = (head);
std::cout << "[->] " ;
while(tmp!=nullptr){
std::cout << tmp->getData() << " ";
tmp = (tmp->getNext());
}
std::cout << std::endl;
}
size_t size() const { return _size; }
V deleteLast(){
int _c{};
ptr<Node> _tmp;
ptr<Node> _lastValue;
_tmp = (head);
if(size()!=0){
while(_tmp!=nullptr){
if(size() == 1){
_lastValue = (head);
head = nullptr;
tail = nullptr;
head = (tail);
_size--;
return _lastValue->getData();
}
else if(_c == size()-2){
_lastValue = (_tmp->getNext());
_tmp->getNext() = nullptr;
tail = (_tmp);
_size--;
}
_tmp = (_tmp->getNext());
_c++;
}
return _lastValue->getData();
} else {
return {};
}
}
};
}
}
#endif // LINKEDLIST_H
#include "linkedlist.h"
#include <string>
int main(){
auto list = std::make_unique<Nyo::Util::LinkedList<std::string>>();
list->pushFront("Bob");
list->add("Carl");
list->add("Mario");
list->add("Elliot");
list->pushFront("Neo");
list->insertAt(0,"Sara");
list->insertAt(4,"Marek");
list->display();
do {
std::cout << "Deleting " << list->deleteLast() << std::endl;
list->display();
} while (!list->isEmpty());
list->pushFront("fSociety");
list->pushFront("Skyler");
list->add("Say_my_name");
list->display();
std::cout << "Printing first and last element: " << (*list)[0] << " " << (*list)[static_cast<int>(list->size())-1] << std::endl;
if(list->find("fSociety")){
std::cout << "__ITEM_FOUND__" << std::endl;
}
return 0;
}
if (isEmpty()) {
instead ofif(isEmpty()){
. Also, no need to useelse
on anif
that always doesreturn
. I'd be more consistent in the usage of blank lines. Also, I'd leave off braces for one-linerif
s:if(_c == index) { break; }
-->if (_c == index) break;
Personally, I dislike "cuddled"else
:} else {
and I'd moveelse {
to the next line. And, where are the comments??? – Craig Estey Sep 2 '16 at 20:54