I have implemented a linked list in C++. I would love to get feedback on how I can improve my code. Should I include more comments to my code or does my code have sufficient logical flow? I would also appreciate comments on how I could make my code more concise. I have tried to make sure to stop all memory leaks. Please let me know if there are more that I have not addressed.
#include <cstdlib>
#include <iostream>
#include <cstdio>
//Node class
template <class T>
class Node{
public:
T data;
Node<T> *next;
Node(T data, Node<T> *next);
};
template <class T>
Node<T>::Node(T data, Node<T> *next){
this->next = next;
this->data = data;
}
//LinkedList class
template <class T>
class LinkedList{
public:
//fields
Node<T> *head;
int size;
//methods
LinkedList();
void push(T data);
void append(T data);
T pop();
T removeLast();
void clear();
int getSize();
void printList();
};
/* LinkedList Constructor
Sets head of the linkedlist to null,
Sets size to 0 */
template <class T>
LinkedList<T>::LinkedList(){
this->head = NULL;
this->size = 0;
}
//getSize:returns the size of the list.
template <class T>
int LinkedList<T>::getSize(){
return this->size;
}
/* push: adds a node to the front of the list,
stores the given data in the node,
increments size of list */
template <class T>
void LinkedList<T>::push(T data){
Node<T> *n = new Node<T>(data, this->head);
this->head = n;
this->size++;
}
/* append: adds a node to the end of the list,
stores the given data in the node,
increments size of list */
template<class T>
void LinkedList<T>::append(T data){
Node<T> *n = new Node<T>(data, NULL);
Node<T> *start = this->head;
if (start == NULL){
this->head=n;
this->size ++;
return;
}
while (start->next != NULL){
start = start->next;
}
start->next = n;
this->size ++;
}
/* pop: removes the node at the front of the list,
returns the associated data. */
template <class T>
T LinkedList<T>::pop(){
Node<T> *h = this->head;
//if list is empty
if (h==NULL){
return 0;
}
//if list has only one node
if (h->next==NULL){
T ret = h->data;
this->head = NULL;
this->size --;
return ret;
}
//if list has multiple nodes
else{
T ret = this->head->data;
this -> head = h->next;
this->size --;
return ret;
}
delete h;
}
/*removes the last node in the list
returns the associated data.*/
template <class T>
T LinkedList<T>::removeLast(){
Node<T> *h = this->head;
//if list is empty
if (h==NULL){
return 0;
}
//if list has only one node
if (h->next==NULL){
return this->pop();
}
//if list has multiple nodes
while (h->next->next != NULL){
h = h->next;
}
T ret = h->next->data;
h->next = NULL;
this->size--;
delete h->next;
return ret;
}
/*removes all of the nodes from the list,
freeing the associated data using the given function */
template <class T>
void LinkedList<T>::clear(){
//if list is empty
if (this->size == 0){
std::cout<<"Cannot Clear Empty List"<<std::endl;
return;
}
Node<T> *h = this->head;
Node<T> *n = NULL;
while (h != NULL) {
n = h->next;
delete h;
h=n;
}
this->head = NULL;
this->size = 0;
std::cout<<"Cleared List"<<std::endl;
}
template <class T>
void LinkedList<T>::printList(){
int i = 1;
//if list is empty
if (this->size == 0){
std::cout<<"Cannot Print Empty List"<<std::endl;
return;
}
Node<T> *n = this->head;
//if there is only one element
if (this->size ==1){
std::cout<<i<<": "<<n->data<<std::endl;
}
while(n){
std::cout<<i<<": "<<n->data<<std::endl;
n = n->next;
i++;
}
delete n;
}
int main(){
LinkedList<int> list;
//testing push
for (int i = 1; i < 6; ++i)
list.push(i);
std::cout<<"After Pushing"<<std::endl;
list.printList(); //testing printList()
std::cout<<"\nSize of list: "<<list.getSize()<<std::endl;//testing getSize()
//testing pop
for (int j = 0; j < 5; ++j){
int output=list.pop();
std::cout<<"Popped: "<<output<<std::endl;
}
std::cout<<"\nAfter Popping"<<std::endl;
std::cout<<"Size of list: "<<list.getSize()<<std::endl;
list.printList();
//testing Append
list.append(0);
list.append(20);
std::cout<<"\nAfter Append"<<std::endl;
std::cout<<"Size of list: "<<list.getSize()<<std::endl; //testing getSize() again
list.printList(); //testing printList() after append
//testing RemoveLast
list.removeLast();
std::cout<<"\nAfter RemoveLast"<<std::endl;
list.printList();
std::cout<<std::endl;
//testing clear
list.clear(); //output: cleared
list.clear(); //output: cannot clear empty list
std::cout<<"\nAfter Clear"<<std::endl;
list.printList();
return 0;
}
Node<T> *ninpushdoesn't allocate a new node, it points somewhere undefined.return 0inpopdoesn't work ifTisn't an arithmetic type (it could be a struct or a class). \$\endgroup\$malloc()andfree()in C++ code. \$\endgroup\$