I am implementing a linked-list, and one of the function asks for the number of nodes in the linked list. However, as the requirement says it needs to be done recursively.
Here is my implementation so far.
class LList {
public:
bool isEmpty() const;
void cons(int x);
int length() const;
private:
struct Node {
int item;
Node* next;
};
Node* head;
}
bool LList::isEmpty() const{
if(head == nullptr)
return true;
else
return false;
}
void LList::cons(int x){
Node* temp = new Node;
temp->item = x;
temp->next = head;
head = temp;
}
I can only do this iteratively, but couldn't make the recursion work.
int LList::length(Node* head) const{
Node* temp = head;
if (temp == nullptr) {
return 0;
}
return 1 + length(temp->next);
}
int LList::length() const {
return length(head);
}
I tried to use a helper function to do the job, but it's saying declaration is incompatible with int LList::length() const
Can anyone help me with this problem?
You are recursing the wrong place: You only have a single LList, so there is nothing to recurse on there. What you want to do instead is to recurse on the Node objects.
Keep your int LList::length() const function, but all it has to do is check if head is nullptr and then call the new recursive function that you are going to make: int LList::Node::length() const. This one then recurses through the next pointers of your Node objects and counts them.
Related
I've start implementing some data structures in C++, starting from Linked Lists.
Coming from a Java background, I'm still wrapping my head around pointers and objects lifespans.
LinkedList:
struct Node
{
int data;
Node *next;
};
class LinkedList
{
private:
Node *head;
Node *tail;
int length;
public:
LinkedList();
~LinkedList();
void addToHead(Node &newHead);
void popHead();
void printList();
};
and then I've implemented it like this:
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(Node& newHead)
{
newHead.next = head;
head = &newHead;
length++;
}
void LinkedList::popHead()
{
Node *currHead = head;
head = head->next;
length--;
}
void LinkedList::printList()
{
Node *curr = head;
while(curr)
{
curr = curr->next;
}
}
Lastly there's a simple main:
int main()
{
LinkedList list;
Node n1 = {3};
Node n2 = {4};
Node n3 = {5};
list.addToHead(n1);
list.addToHead(n2);
list.addToHead(n3);
list.printList();
list.popHead();
list.printList();
return 0;
}
This a rather naive implementation, and I was wondering if I had to provide a proper destructor which deletes the Node* pointers upon iteration.
Whenever I've tried to add it, the program results in a memory error, and I was thinking that the memory being allocated is being also deallocated at the end of the main, since all the Node*s live there.
Should I fix my destructor? Should I change the whole interface?
Thanks in advance!
Although there are no memory leaks in your code as it stands, I think you should change your interface.
Your linked list isn't doing what you probably think its doing - taking ownership of its contents. A linked list that doesn't own its contents is a strange beast and probably something you did not intend.
One easy way to make it take ownership is to change your design to use std::unique_ptr instead of raw pointers. Your addToHead function would then be change to take std::unique_ptr r-value references pointers (or simply raw pointers that create new std::unique_ptr internally if that's too advanced)
Here is your implementation changed to use std::unique_ptr. Its a bit rough-and-ready, but should get you on your way:
#include <memory>
struct Node
{
Node(int i) : data(i)
{}
int data;
std::unique_ptr<Node> next;
};
class LinkedList
{
private:
std::unique_ptr<Node> head;
Node *tail;
int length;
public:
LinkedList();
~LinkedList();
void addToHead(std::unique_ptr<Node>&& newHead);
void popHead();
void printList();
};
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(std::unique_ptr<Node>&& newHead)
{
newHead->next = std::move(head);
head = std::move(newHead);
length++;
}
void LinkedList::popHead()
{
head = std::move(head->next);
length--;
}
void LinkedList::printList()
{
auto* curr = head.get();
while(curr)
{
curr = curr->next.get();
}
}
int main()
{
LinkedList list;
list.addToHead(std::make_unique<Node>(3));
list.addToHead(std::make_unique<Node>(4));
list.addToHead(std::make_unique<Node>(5));
list.printList();
list.popHead();
list.printList();
return 0;
}
I have the following code to insert in the bst however, it fails to insert all the nodes except for the root. Any idea what I am doing wrong?
class Node
{
public:
int data;
Node* right;
Node* left;
Node(int data)
{
this->data = data;
}
Node() {}
};
class BST
{
public:
Node* head;
void insert(int data)
{
if (head == nullptr)
{
head = new Node(data);
head->data = data;
}
else
{
// head = new Node(data);
insertNode(data, head);
}
}
void insertNode(int data, Node* head)
{
if (head == nullptr)
{
head = new Node(data);
return;
}
if (head)
{
Node* temp = head;
if (temp->data > data)
{
insertNode(data, temp->left);
}
else if (temp->data <= data)
insertNode(data, temp->right);
}
}
};
The parameter head in insertNode shadows the member variable named head.
However, while that's a really bad practice, the other answer is the true reason for your error, so please select his answer instead (once you get it working, of course).
I'd recommend changing the signature of insertNode to
void insertNode(int data, Node*& node)
Also, you don't need to check for head == nullptr in insert. You have a duplicate check in insertNode
So insert could look like this:
void insert(data) {
insertNode(data, head);
}
Finally, you're not initializing head within the constructor. It's possible that head will be initialized to something other than nullptr, especially if you compile this in release mode. Add a constructor like this:
BST() : head(nullptr) {
// Other init stuff here if necessary
}
You'll also want to make Node* head a private data member instead of public.
insertNode() takes a copy of the pointer, so changes made inside the function have no effect on the actual pointer in the tree. What you want to do is take a reference to the pointer:
void insertNode(int data, Node*& head)
In your function " insertNode" you are using if(head) , this if will work only if head == 1 , and head is never equals to 1 because its a pointer , so this "if" is not working.!
I'm building my own linked list class and I'm having some issues figuring out how to write some functions to help me traverse this list. This is my first time building a linked list from scratch, so if my approach is unconventional please let me know what might be more conventional.
I'd like write a function, within the List class that allows me to increment to the next element called getNext() as well as one that getPrev();
I wrote getNext like this:
T* getNext(){return next;}
However it tells me next is not declared within the scope. I'd also like to write a function that lets me access and modify the object within the list. I was considering using the bracket operator, but first I need to write a function to return the data member. Perhaps If I take a similar approach as I did within my pop functions.. thinking about it now. However, I'd still appreciate any advice.
Here is my List class:
#ifndef LIST_H
#define LIST_H
//List Class
template <class T>
class List{
struct Node {
T data;
Node *next;
Node *prev;
//Constructs Node Element
Node(T t, Node* p, Node* n) { data = (t); prev = (p); next = (n); }
// T *getNext() {return next;}
};
Node *head;
Node *tail;
public:
//Constructor
List() { head = NULL; tail=NULL; }
//Destructor
~List() {
while(head){
Node * temp(head);
head = head->next;
delete temp;
}
}
//is empty
bool empty() const {return (!head || !tail ); }
operator bool() const {return !empty(); }
//Push back
void push_back(T data) {
tail = new Node(data, tail, NULL);
if(tail->prev) //if the node in front of tail is initilized
tail->prev->next = tail;
if( empty() )
head = tail;
}
//Push front
void push_front(T data) {
head = new Node(data, NULL, head);
if(head->next)//if the node following head is initilized
head->next->prev = head;
if( empty() )
tail = head;
};
T pop_back() {
if( empty() )
throw("Error in List: List is empty\n");
Node* temp(tail);
T data(tail->data);
tail = tail->prev;
if( tail )
tail->next = NULL;
else
head = NULL;
delete temp;
return data;
}
T pop_front() {
if (empty())
throw("Error in List: List is empty\n");
Node* temp(head);
T data(head->data);
head = head->next;
if(head)
head->prev=NULL;
else
tail = NULL;
delete temp;
return data;
}
T getNext(){return next;}
};
#endif
getNext should be part of the struct Node and return a Node*
Node* getNext() { return next; }
Then from that you can get the value.
If you have to have it part of the list itself, which I would not recommend it will need to take a parameter of what Node you would like the next of:
Node* getNext(Node* n) {return n->next;}
Again, I recommend the first option.
Here is an approximate whole class with both of these:
template<typename T>
class List {
public:
struct Node {
Node* next, prev;
T data;
//some constructor and stuff
Node* Next() {return next;}
}
//some constructors and other functions
Node* getNext(Node* _n) {return _n->Next();}
}
then to use:
int main() {
List<int> l;
//add some stuff to the list
//get the head of the list
List<int>::Node* head = l.head; //or some corresponding function
//then
List<int>::Node* next = head->Next();
//or
List<int>::Node* next2 = l.getNext(head);
}
for starters getNext() should not return a pointer to the template class, it should return a pointer to the Node structure.
So it should be
Node* getNext(){return next;}
Because it's a member of Node struct and getNext is member of List. You should access it from an object of type Node.
Please delete.
I want to implement a linked list. Unfortunately I'm not sure whether I'm on the right track.
#include <iostream>
using namespace std;
class Node {
friend class List;
public:
int value;
private:
Node *next;
};
class List {
public:
List ();
~List ();
Node * first() const;
Node * next(const Node * n) const;
void append (int i);
Node* head;
};
List::List() {
Node* head = new Node();
}
List::~List() {
while(head != NULL) {
Node * n = head->next;
delete head;
head = n;
}
}
Node * List::first() const {
return head; // this could also be wrong
}
Node * List::next(const Node * n) const {
return n + 1; // ERROR
}
void List::append(int i) {
Node * n = new Node;
n->value = i;
n->next = head;
head = n;
}
int main(void) {
List list;
list.append(10);
return 0;
}
When I try to return an element in next() I get this error:
In member function ‘Node* List::next(const Node*) const’:|
error: invalid conversion from ‘const Node*’ to ‘Node*’ [-fpermissive]|
Could somebody please help me?
EDIT:
I've updated the error-line.
I think what you mean to be doing is returning the Node's next:
Node * List::next(const Node * n) const {
return n->next;
}
You would use pointer arithmetic if this were an array where the size of each object was constant, but linked lists can't use pointer arithmetic. If you have an iterator, you could use the '++' operator to get the next object, but with this just stick to returning the node's next field.
I'm assuming this will also work because even though next is declared as private, you've made List a friend.
You are thinking that consecutive nodes are in consecutive blocks of memory, and they are not. Linked lists have nodes in random places in memory, which is why "next" points to the NEXT node. You cannot increment or add as you are trying (well you can, but semantically it would be incorrect.)
I'm trying to create a doubly-linked list with the null object model. So far, I've implemented a method to add a node to the beginning of the list and a method to display the node. My problem is that the display function always displays 0. Can anyone point out where I've gone wrong and how to fix it? Also, am I on the right track to correctly implementing the null object model here?
Note: This is a school assignment. Please don't just post a solution without an explanation. I want to learn and understand what's going on here.
Edit: After fixing the display problem, I have another: When calling getHead() or getTail() with a list that is empty or has nodes, it keeps wanting to use self() from the node class, rather than the nullNode class (in the event of an empty list) or elementNode class (in the event of a list with nodes). I'm stuck on how to fix this.
If I print out the addresses of container.getNext() and container (for an empty list), both addresses are the same so shouldn't adding ->self() to the end call the self() method from the nullNode class?
class node {
public:
node(){/* Do nothing */}
node(int e){ element = e; }
int getData(){ return element; }
void setData(int e){ element = e; }
friend class list;
protected:
node* getNext(){ return next; }
void setNext(node* n){ next = n; }
node* getPrev() { return prev; }
void setPrev(node* n){ prev = n; }
node* self();
private:
int element;
node* next;
node* prev;
};
class nullNode : public node{
public:
nullNode(){/* Do nothing */}
int getData(){ return NULL; }
void setData(int e){ /* Do Nothing */ }
node* getNext(){ return head; }
void setNext(node* n){ head = n; }
node* getPrev() { return tail; }
void setPrev(node* n){ tail = n; }
node* self(){ return NULL; }
private:
node* head;
node* tail;
};
class elementNode : public node{
public:
elementNode(){/* Do nothing */}
elementNode(int element){
setData(element);
}
int getData(){ return node::getData(); }
void setData(int e){ node::setData(e); }
node* getNext(){ return node::getNext(); }
void setNext(node* n){ node::setNext(n); }
node* getPrev() { return node::getPrev(); }
void setPrev(node* n){ node::setPrev(n); }
node* self(){ return this; }
};
class list{
public:
list();
node* getHead(){ return (container.getNext())->self(); }
node* getTail(){ return (container.getPrev())->self(); }
node* addHeadNode(int e);
void removeNode(node* n);
void insertBefore(node* n, int e);
void insertAfter(node* n, int e);
void displayNode(node *n);
private:
nullNode container;
};
list::list()
{
container.setNext(&container);
container.setPrev(&container);
}
node* list::addHeadNode(int e)
{
node* foo = new elementNode(e);
foo->setPrev(&container);
foo->setNext(container.getNext());
container.getNext()->setPrev(foo);
container.setNext(foo);
return foo;
}
void list::displayNode(node* n)
{
cout << "Node Data: " << n->getData() << endl;
}
int main()
{
list myList;
node* myNode;
myNode = myList.addHeadNode(5);
myList.displayNode(myNode);
return 0;
}
elementNode(int element)
{
node e;
e.setData(element);
}
What is this code doing? You create node e, but it appears to then be thrown away and not added to any list.
The problem hides in
elementNode(int element){
node e;
e.setData(element);
}
What is going on here? First you create an instance of the node class and then call its setData member function. Sure enough e is modified with the value of element but the very next moment both e and element are vanished out of existence because the scope where they were initialized has ceased to its end (terminated by }) while the information in element hasn't been saved anywhere.
However, if you replace the above code with
elementNode(int element){
setData(element);
}
it calls the inherited setData member function, the value of element is saved, and the program outputs 5 as expected.
Your elementNode constructor is trying to initialize it's node part:
elementNode(int element){
node e;
e.setData(element);
}
You actually just construct an unrelated node then discard it.
What you want is to call your superclass constructor, which can be done in the subclass constructor's initialization list:
elementNode(int element) : node(element) {
}