How to find the end of a linked list - c++

We are creating LinkedLists in our data structures class. The following is the declaration for the class.
template <class T>
class LinkedList
{
public:
T m_data; // Data to be stored
LinkedList<T>* m_next; // Pointer to the next element in the list
// ...
};
The teacher told us which functions to implement. I am currently trying to implement this:
// Purpose: accessor function for last element node
// Returns: pointer to the last element's node in the list;
// returns NULL if list is empty
LinkedList<T>* getLastPtr();
I am not sure what code you need to see, so here is a minified version of my code which demonstrates the problem:
template <class T>
class LinkedList
{
public:
T m_data;
LinkedList<T>* m_next;
LinkedList() : m_next(NULL) {}
void insert_front(const T& x);
LinkedList<T>* getLastPtr();
}
// INSERT FRONT
template<typename T>
void LinkedList<T>::insert_front(const T& x){
LinkedList<T> *tmp;
tmp = new LinkedList<T>;
tmp->m_data = m_data;
tmp->m_next = m_next;
this->m_next = tmp;
this->m_data = x;
}
// GET LAST POINTER
template<typename T>
LinkedList<T>* LinkedList<T>::getLastPtr(){
const LinkedList<T>* runner;
const LinkedList<T>* tmp; //one behind runner
runner = this;
while (runner->m_next != NULL){
tmp = runner;
runner = runner->m_next;
cout<<"tmp: "<<tmp->m_data<<endl; //FIX DIS
cout<<"runner: "<<runner->m_data<<endl; //FIX DIS
}
return tmp->m_next;
}
We are also given a tester but for sake of simplification I will only post the section I am having issues with:
LinkedList<int> A;
//TEST : Inserting 13 numbers to a
cout << endl << "TEST : Inserting 13 numbers into A" << endl;
for (int k=0; k<13; k++){
A.insert_front(k*2);
}
// TEST : Acessing last element
cout << endl << "TEST : Acessing last element" << endl;
LinkedList<int>* p = A.getLastPtr();
cout << "Last = " << p->m_data << endl;
My issue is that when I use the function getLastPtr() it returns a bunch of random numbers. I do not know what I am doing wrong since my getAtPtr() function works properly and I am using almost identical code.
I think it has something to do with pointing to the wrong thing OR my last element isn't pointing to NULL (which should be for checking purposes).
Here you can see a demo of the problem: http://ideone.com/mDXKsV

in getLastPtr() i was going to the last element in the list which pointed to NULL. I was originally grabbing data from THAT point and therefore it was gibberish. I learned that i had to grab the element behind the Null so i made a follower to the runner, but i also cleaned up a bunch of my code especially for insert_first.

Related

Implement iterator of a circular list

I'm trying to implement a class of Circular List with a nested class of iterator and I wrote like this:
template <class T>
class CircularList {
struct Item {
T data;
Item* next;
};
Item* head;
int size;
public:
CircularList() {
head = new Item();
head->next = head;
}
int sizeList() { return size; }
void push(T data) {
Item* i = new Item();
i->data = data;
i->next = head->next;
head->next = i;
size++;
}
class CircularListIterator {
Item* p;
CircularListIterator() {
p = head->next;
}
bool hasNext() {
if(p->next != head) {
return true;
}
return false;
}
T next() {
T data_temp = p->data;
p = p->next;
return data_temp;
}
};
CircularListIterator* iterator() {
return new CircularListIterator();
}
};
int main() {
CircularList<string>* letters = new CircularList<string>;
letters->push("d");
letters->push("c");
letters->push("b");
letters->push("a");
Iterator<string>* it= new Iterator<string>;
it = letters->iterator();
while (it->hasNext()) {
cout<< it->next() << "," << endl;
}
return 0;
}
But the Iterator is not working when I try to create an iterator in the main function, It said that it wasn't declared in the scope and has no member of it.
Assuming by "in the main class" you mean in the main function, the problem is quite straightforward: you're trying to construct a ::Iterator<string>, but there is no class in the global namespace (or anywhere else, in this code sample) called Iterator! You could try constructing a CircularList<string>::CircularListIterator - that's at least a class that exists - but it wouldn't work because the iterator needs to be associated with a CircularList object for it to be able to access member variables like head.
The correct thing to do here is to promote the iterator function - the one that returns a CircularListIterator* - out of the CircularListIterator class and into the CircularList class. Then, in your main function, you can call letters->iterator() and it'll return a CircularListIterator* for the letters object.
Now, CircularListIterator doesn't inherit from any other iterator classes - neither the (nonexistent-in-this-code Iterator you've typed it as, nor the C++ std::iterator or any of its variants) - so you can't assign it to it or probably even compile the code that references Iterator. To make CircularListIterator a subclass of std::iterator, you'll need to extend std::iterator<Category, T> with the appropriate category. See https://www.cplusplus.com/reference/iterator/iterator/ for more information on the std::iterator class template, including an example of implementing it.

Iterate over elements where not all the elements should have a value

I'm not sure how to describe this. I have to iterate through objects which are connected by pointers with each other, However the first element shouldn't have values stored in its class just the pointer to the next element.
I came up with a small class hierarchy. If I use it like that I have to cast the base class to the derived element. It only seems to work with a dirty cast.
Is there a better solution?
Here the example code:
#include <iostream>
struct Basenode {
Basenode* next;
};
struct Skipnode : Basenode {
Skipnode(int in_key, int in_value);
int key;
int value;
};
Skipnode::Skipnode(int in_key, int in_value)
: key{ in_key }, value{ in_value }
{
}
int main()
try {
Basenode head; // no key and value
Skipnode first(4, 2); // key and value
Skipnode second(8, 2);
Basenode* p = &head;
head.next = &first; // fine
first.next = &second; // fine
// p = p->next->key; // not accesible because is Basenode not derrived Skipnode
std::cout << static_cast<Skipnode*>(p->next)->key; // fine but diryt cast slicing ?
std::cin.get();
}
catch (std::runtime_error& e) {
std::cerr << e.what() << "\n";
std::cin.get();
}
catch (...) {
std::cerr << "unknown error " << "\n";
std::cin.get();
}
Edit: it was asked int the comments why i need this anyway. I think i gave a to limited example.
I need it to implement a skiplist. Many algorithms of it require to start on a element before the first element. The head element. I could make it a normal node and put in dummy values for the values but it didnt seem right. So now i came up with this ugly solution from youre suggestions to start on the head elements.
Heres a snippet with the copy constructor as example.
class Skiplist {
public:
//...
Skiplist(const Skiplist& other); // copy constructor
//...
private:
struct Skipnode; // forward declaration so Basenode can have Skiplist*
struct Basenode { // Empty node, mainly created to represent head element.
// Is there a way to get a empty head with no key / values without using this ?
Basenode(int in_level);
Basenode(const std::vector<Skipnode*>& in_next);
std::vector <Skipnode*> next;
};
struct Skipnode : Basenode { // derived so with Basenode* we can start the iteration of the node on head
Skipnode(value_type val, int in_level);
Skipnode(value_type val, const std::vector<Skipnode*>& in_next);
value_type value; // first key / second mapped type = value
//key_type key;
//mapped_type value;
};
Basenode head{ 0 }; // element before first element containg pointers to all the first elements of each level
//...
};
Skiplist::Skiplist(const Skiplist& other) // copy constructor
:head{ other.head }, top_level{ other.top_level }, random_engine{ other.random_engine }
// on the first level let the other Skiplist present its elements and make a deep copy of them
// now still the higher levels point to the other node so this is fixed in the second part
// then the next level pointers are installed linked to the elements of the new node
{
if (top_level == 0) return; // no elements are present so dont bother to allocate nodes
{
// installment of lowest level, each element is located here
Skipnode* other_node = other.head.next[0];
Basenode* current_position = &head;
while (other_node != nullptr) {
Skipnode* new_node = new Skipnode{ other_node->value,other_node->next };
current_position->next[0] = new_node;
current_position = current_position->next[0];
other_node = other_node->next[0];
}
current_position->next[0] = nullptr;
}
// installment of the other levels
for (size_type curr = 1; curr < top_level; ++curr) {
Basenode* current_position = &head; // the current position of the level[curr]
Skipnode* next_position = current_position->next[curr]; // next position after curr containing still pointers to the other skiplist
Basenode* lowest_position = &head; // lowest level position used to find the new pointers and attach them "behind" current
while (lowest_position != nullptr && next_position != nullptr) {
if (lowest_position->next[0]->value.first == next_position->value.first) { // check by unique key, address of next pos is still of the other skiplist
current_position->next[curr] = lowest_position->next[0]; // lowest is the valid address of new node
current_position = current_position->next[curr];
next_position = next_position->next[curr]; // go to next element of other node
if (next_position == nullptr) { // case end is reached
current_position->next[curr] = nullptr;
current_position = current_position->next[curr];
}
}
else { // forward position of lowest level until other key == next position key
lowest_position = lowest_position->next[0];
}
}
}
}
See here for a basic explanation how a skiplist is organized:
https://en.wikipedia.org/wiki/Skip_list
The whole code is on codereview:
https://codereview.stackexchange.com/questions/197752/non-generic-skip-list-implementation-in-c-version-2
All the things #SomeProgrammerDude is saying, or:
I don't see a need for class BaseNode at all. Why can't we just have (all other things being equal):
SkipNode *head = &first;
...
Or better yet a class called (for example) SkipNodeList that handles all aspects of managing and iterating through a list of SkipNodes.
Of course, this is all a bit silly anyway, just use std::list (or std::forward_list) for this and benefit from all that STL goodness.
Or you can derive from one of these to add your own functionality (such as a mutex to make the list threadsafe or keeping track of the number of elements currently in the list, as suggested by #iMajuscule).
Yes, there is a better way:
Forward-declare Skipnode, and in BaseNode, use a pointer to SkipNode, this way you don't have to cast:
struct Skipnode;
struct Basenode {
Skipnode* next;
};
Also, to illustrate how this design where Skipnode inherits from Basenode could make sense (related to the discussion in the comments), we can imagine having a member in Basenode counting how many elements are next (counting the one in the next member and its successors)

Linked-list in C++ using references instead of pointers

Suppose I want to create an unmodifiable linked-list (i.e. it can only be traversed, no nodes can be added or removed once it was initially created). This could be easily implemented by:
struct ListNode
{
int value;
ListNode* nextNode;
}
My question is .... Would it be possible to use references instead of pointers?
struct ListNodeWithRefs
{
int value;
ListNodeWithRefs &nextNode;
}
I am not sure it would provide any performance gain at all but ... this question popped up while coding and my answer so far is no but I could be missing something.
In principle, nothing prevents you from using references, and constructing list elments like this:
ListNodeWithRefs::ListNodeWithRefs(ListNodeWithRefs &next):
nextNode(next)
{}
But there is a chicken and egg problem because next also enforces its next element to exist at its creation and so on ...
Note: I think my question can also be applied to defining the list as:
struct ListNodeConst
{
int value;
const ListNode* nextNode;
}
This is typical of a cons-list in functional languages:
data List a = Empty | Node a (List a)
The trick is though, List a is a full type and can refer either to Empty OR another node (which is why it can terminate).
In order to achieve this in C++, you could take advantage of either a union (but it's not that well supported) or of polymorphism.
template <typename T>
struct ListBase {
enum class Kind { Empty, Node };
explicit ListBase(Kind k): _kind(k) {}
Kind _kind;
};
And then:
template <typename T>
struct EmptyList: ListBase<T> {
EmptyList(): ListBase<T>(Kind::Empty) {}
};
template <typename T>
struct ListNode: ListBase<T> {
ListNode(T const& t, ListBase<T>& next):
ListBase<T>(Kind::Node), _value(t), _next(next) {}
T _value;
ListBase<T>& _next;
};
And now, you don't have a chicken & egg problem any longer; just start from an instantiation of EmptyList<T>.
Note: the presence of _kind in the base class is not that OO, but it makes things closer to the functional example by tagging which alternative is used.
Take a look at this example by sbi, it seems to work: https://stackoverflow.com/a/3003607/1758762
// Beware, un-compiled code ahead!
template< typename T >
struct node;
template< typename T >
struct links {
node<T>& prev;
node<T>& next;
link(node<T>* prv, node<T>* nxt); // omitted
};
template< typename T >
struct node {
T data;
links<T> linked_nodes;
node(const T& d, node* prv, node* nxt); // omitted
};
// technically, this causes UB...
template< typename T >
void my_list<T>::link_nodes(node<T>* prev, node<T>* next)
{
node<T>* prev_prev = prev.linked_nodes.prev;
node<T>* next_next = next.linked_nodes.next;
prev.linked_nodes.~links<T>();
new (prev.linked_nodes) links<T>(prev_prev, next);
next.linked_nodes.~links<T>();
new (next.linked_nodes) links<T>(next, next_next);
}
template< typename T >
void my_list<T>::insert(node<T>* at, const T& data)
{
node<T>* prev = at;
node<T>* next = at.linked_nodes.next;
node<T>* new_node = new node<T>(data, prev, next);
link_nodes(prev, new_node);
link_nodes(new_node, next);
}
How does the list end?
You will need at least two types: the end and not. You also need lifetime management. And either runtime or static knowledge of which type.
A completely static implementation could be done, where each node is its own type that knows how far it is to the end.
Or you could just have an unintialized buffer, and create elements off it in reverse order.
A circle is also possible. Make the first reference refer to the last element you construct.
No. Reasons:
You cannot insert a node if nextNode is a reference.
What should nextNode refer to if this is list tail?
As #Vlad said, the problem with references is that you will need a final object.
The good news is that, in principle, you can still have a cyclic list, if you have a use for it.
This is a fundamental thing, if the "next" element is a non-nullable reference means that there is always a next element, that is, the list is either infinite or, more realistically, it closes on itself or into another list.
Taken the exercise further is quite interesting and strange.
Basically the only thing that seems to be possible is to defined the equivalent of the a node (which also represents the list).
template<class T>
struct node{
T value; // mutable?
node const& next;
struct circulator{
node const* impl_;
circulator& circulate(){impl_ = &(impl_->next); return *this;}
T const& operator*() const{return impl_->value;}
friend bool operator==(circulator const& c1, circulator const& c2){return c1.impl_ == c2.impl_;}
friend bool operator!=(circulator const& c1, circulator const& c2){return not(c1==c2);}
};
circulator some() const{return circulator{this};}
};
The elements have to live in the stack and the list is static (well, references are not rebindable anyway) and the links have to be const references!
Eventually the value can be made then mutable apparently (probably safe?).
(At this point one wonders how is this different from a stack array references by a modulo indices.)
There is only one way to construct the node/list object, that is to close it with itself (or with other preexising node). So the resulting list are either circular or "rho" shape.
node<int> n1{5, {6, {7, n1}}};
auto c = n1.some();
cout << "size " << sizeof(node<int>) << '\n';
do{
cout << *c << ", ";
c.circulate();
}while(c != n1.some()); //prints 5, 6, 7
I wasn't able to make a node that is not trivially constructible (aggregate?).
(Adding any sort of basic constructor produced segmentation faults for a reason I can't understand, both in gcc and clang).
I wasn't able to encapsulate the node in a "container" object for the same strange reason.
So making an object that could be constructed like this was impossible to me:
circular_list<int> l{1,2,3,4}; // couldn't do this for obscure reasons
Finally, since a proper container cannot be constructed it is not clear what is the semantics of this object, for example when two "lists" are equal? what doesn't mean to assign? or assign between list of different sizes?
It is a quite paradoxical object, with no general value or reference semantics apparently.
Any comments or improvements are welcomed!
I might be off the mark, but this works
struct Node;
struct Node {
using link = std::reference_wrapper<Node>;
Node( char data_ = 0)
: next({*this})
, data( data_ == 0 ? '?' : data_ )
{}
bool is_selfref() const noexcept {
return (this == & next.get());
}
char data;
link next;
};
The usual tests
Node A('A');
Node B('B');
Node C('C');
assert( A.is_selfref() == B.is_selfref() == C.is_selfref());
A.next = B; B.next = C;
assert(! A.is_selfref() && ! B.is_selfref() );
assert( C.is_selfref() );
assert( 'A' == A.data );
assert( 'B' == A.next.get().data );
assert( 'C' == A.next.get().next.get().data );
// C.next == C
// for those who feel safe seeing the END
Node END(127);
C.next = END;
Of course, as long as all Node's stay in the scope we are all ok here. Otherwise not. Strange and wonderful. Very limited utility?
That was quite tricky but this worked :
#include <iostream>
#include <typeinfo>
class Last {
public:
int x;
int last;
Last(int i) {
std::cout << "parent constructor(" << i << ")\n";
x = i;
last = 1;
}
};
struct fourptr {
int v1, v2;
void *p1, *p2;
};
class chain : public Last {
public:
chain(int i) : Last(i) {
std::cout << "child constructor(" << i << ")\n";
last = 0;
}
void viewandnext() {
struct fourptr *fp = (struct fourptr *) this;
std::cout << x << ", this = " << this
<< ", sizeof *this = "<< sizeof * this
<< ", * this = {" << fp->v1 << ", " << fp->v2 << ", "
<< fp->p1 << ", " << fp->p2 << "}"
<< "\n";
if (last == 0) ((chain &)next).viewandnext();
}
Last & fn(int x) {
Last * e = (x>0) ? new chain(x-1) : new Last(x-1);
return *e;
}
Last & next = fn(x); // This is not a pointer but a reference
};
int main(void) {
chain &l = *(new chain(8));
std::cout << "sizeof l = "<< sizeof l << "\n";
l.viewandnext();
}
A simple way to avoid a chicken-egg problem for a list with references is to remember that firstly your object memory is allocated, then your constructor is called. Moreover, access to this pointer is guaranteed inside of a constructor by C++ standard.
Neat way to resolve this:
struct node {
int data;
node& next;
node(node& n, int d): next(n), data(d) {}
};
node tl(tl, 69); // tl is already in the scope!

C++ linked list implementation

i am working on an assignment where i am asked to implement a linked list in c++. so far everything is working great except for when i am creating a new list. in my method create_list(). after i assign content and an id number to my Field and try to call GetNext() i get an error saying: Request for member 'GetNext()' in 'Node' which is a non-class type '*Field'. I'm still new to the C++ syntax and object oriented programming. What am I doing wrong? I thought by using the line Field *Node = new Field(SIZE, EMPTY); that my variable Node would be of class type Field...?
#include <iostream>
#include <ctype.h>
using namespace std;
typedef enum { EMPTY, OCCUPIED } FIELDTYPE;
// Gameboard Size
int SIZE;
class Field {
private:
int _SquareNum;
FIELDTYPE _Content;
Field* _Next;
public:
// Constructor
Field() { }
// Overload Constructor
Field(int SquareNum, FIELDTYPE Entry) { _SquareNum = SquareNum; _Content = Entry; }
// Get the next node in the linked list
Field* GetNext() { return _Next; }
// Set the next node in the linked list
void SetNext(Field *Next) { _Next = Next; }
// Get the content within the linked list
FIELDTYPE GetContent() { return _Content; }
// Set the content in the linked list
void SetContent(FIELDTYPE Content) { _Content = Content; }
// Get square / location
int GetLocation() { return _SquareNum; }
// Print the content
void Print() {
switch (_Content) {
case OCCUPIED:
cout << "Field " << _SquareNum << ":\tOccupied\n";
break;
default:
cout << "Field " << _SquareNum << ":\tEmpty\n";
break;
}
}
}*Gameboard;
here is my create_list() method:
void create_list()
{
int Element;
cout << "Enter the size of the board: ";
cin >> SIZE;
for(Element = SIZE; Element > 0; Element--){
Field *Node = new Field(SIZE, EMPTY);
Node.GetNext() = Gameboard; // line where the error is
Gameboard = Node;
}
}
. is used for addressing members in objects and references to objects. Node, however, is a pointer to an object. So you need to turn it into a reference before you can use it with .. This means doing (*Node).GetNext(). Or you can use the shorthand: Node->GetNext() - these two are exactly equivalent.
A good mnemonic to use is that you use the pointy operator with pointers :)
No in the declaration
Field *Node = new Field(SIZE, EMPTY);
Node is of type pointer to Field.
The fix is simple if you have a pointer to a class and you want to access a member of that class use ->.
Node->GetNext() = Gameboard;
I think your code has other errors, and I don't think that even with this 'fix' it's going to work. Probably what you really want is
Node->SetNext(Gameboard);
You're calling Node.GetNext(), but Node is a pointer. You need to use the -> operator instead of the . operator, as in Node->GetNext().
The function must returns a reference value if you want to set as a l-value.
You code need some changes:
// Get the next node in the linked list
Field& GetNext() { return *_Next; }
then you can use the function as a l-value
Node->GetNext() = *Gameboard;

Mixing abstract classes and templates, a recipe for disaster?

I'm having problems with the following situation. I have three classes that are involved in this mixup. List, ListNode, City. I have a List<City *>, where the list will be made up of a set of ListNode<City *> (standard wrapper around the list nodes).
City is an abstract class, so there are several classes that inherit from it that could be placed in this list and accessed polymorphically. The List class has a getHead() method which returns a pointer to a ListNode that is the head.
Any city has a population, so to access the populations, I'd expect the following to work. It's not, thus my question. I broke it down into pieces to make it simpler along the way:
ListNode<City *> *head= country->city_list->getHead();
City *headnode = *head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
getPopulation() returns an integer. country is defined as List<City*> *city; Any help on how I could figure out my problem would be greatly appreciated.
edit adding more code for better idea of what I'm working with. First, ListNode:
template <class T>
class ListNode
{
public:
ListNode() {next = 0;node = 0;};
ListNode(T *t) {node = t; next = 0;};
ListNode(const ListNode &l)
{
//long copy constructor. snip.
};
T *getNode() const { return node; }
ListNode *getNext() const { return next; };
private:
T *node;
ListNode *next;
};
Now, here is what might relevant in the List class..
template <class T>
class List
{
public:
List()
{
head = 0;
size = 0;
};
List(ListNode<T> *t)
{
head = t;
size = 1;
};
List(T *t)
{
head = new ListNode<T>(t);
size = 1;
};
List(const List<T> &t)
{
// long copy constructor. snip.
};
//bunch of irrelevent methods.
ListNode<T> *getHead() const {return head;};
List &operator+=(T &t)
{
this->insert(&t);
size++;
return (*this);
};
private:
List &insert(T *t)
{
ListNode<T> *current = head;
if (current == 0)
{
head = new ListNode<T>(t);
}
else
{
while (current->getNext() != 0)
{
current = current->getNext();
}
current->setNext(new ListNode<T>(t));
}
return (*this);
};
ListNode<T> *head;
int size;
};
I have a hunch that the process of inserting might be the problem. I insert with the List class's += operator, shown in the List implementation above. It calls the private insert method shown above, as well. It looks like this:
City *somecity = new City(x,y,z); //some parameters. integers.
*city_list += somecity; // where city_list is a List.
I think you've got a variable scoping problem.
Your ListNode class contains a pointer to the node value. Your ListNode constructor takes in a pointer to the node value and saves it.
The problem is if that pointer is to a local variable that then goes out of scope. Your ListNode's node pointer is now pointing to an object that doesn't exist. e.g. in this example
addToList(List<int>& myList)
{
int x = 3;
myList += x; // pointer to x is in the list
}
// Out of scope; x no longer exists, but myList has a pointer to it.
// Accessing this node will result in an error.
There are a couple possible remedies:
Have your ListNode contain values rather than pointers. The drawback here is that you will be making copies of the values
Implement ListNode using a reference counted smart pointer which will manager the lifetime of the object.
Well, what you could do is:
ListNode<City *>* head = new ListNode<City*>(country->city_list->getHead());
City* headnode = head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
It will take the existing City (on the memory) and put it at the head of the List node, and so on.
and if you want to copy them, maybe you could just make this:
ListNode<City *>* head = new ListNode<City*>*(new City(country->city_list->getHead()));
City* headnode = new City(head->getNode());
cout << "Test: " << headnode->getPopulation() << endl;
Hope it will help you.