Setting up parameter for function within Link List - c++

I created at doubly link list and want to test out my count function within list class.
the count function is given with a pointer to an abitrary node and count how many nodes in the list.
the problem I have right now is to set up an variable/object that I can put it in count function parameter in main(). For example, the pointer can be pointing the middle node in the list. basically any random node that user might be pointing such as head->next-next or tail->prev->prev in the list.
#include "pch.h"
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;
template <class T>
class node {
public:
T data;
node<T> *next;
node<T> *prev;
//node() {};
node(T newdata):data(newdata){ next = nullptr; prev = nullptr; }
};
template <class T>
class list {
node<T> *head;
node<T> *tail;
public:
list() { head = nullptr; tail = nullptr; }
void insert_head(int newval) {
node<T> *curr = new node<T>(newval);
if (head == nullptr) {
head = tail = curr;
return;
}
tail->next = curr;
curr->prev = tail;
tail = curr;
return;
}
void print() {
node<T>*curr = head;
while (curr != nullptr) {
cout << curr->data << endl;
curr = curr->next;
}
}
int count(node<T>* rannode) {
int count = 0;
node<T> *tohead = rannode;
node<T> *totail = rannode;
while (totail->next != nullptr) {
count++;
totail = totail->next;
}
while (tohead != nullptr) {
count++;
tohead = tohead->prev;
}
return count;
}
};
int main() {
list<int> test;
test.insert_head(1);
test.insert_head(2);
test.insert_head(3);
test.insert_head(4);
test.insert_head(5);
test.print();
test.count(??)
return 0;
}
``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ```

Related

Linked list c++ insertback

I am really new to data structures. I am trying to figure out why my insertback() function doesn't work. The first print does 3,2,1 but the second doesn't print anything. I think it has something to do with head, but I'm not really sure. Please help.
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
class lst
{
public:
void Insertfron(int x);
void Print();
void Insertback(int x);
private:
Node* head;
};
void lst::Insertfron(int x)
{
Node* temp = new Node;
temp->data = x;
temp->next = head;
head = temp;
}
void lst::Print()
{
Node* temp = head;
while(temp->next!=NULL)
{
cout<<temp->data<<' ';
temp=temp->next;
}
cout<< endl;
}
void lst::Insertback(int x)
{
Node* backinst = new Node;
backinst->data = x;
backinst->next = NULL;
Node* temp = head;
while(temp->next!=NULL)
{
temp = temp->next;
}
temp->next = backinst;
}
int main()
{
lst listt;
listt.Insertfron(1);
listt.Insertfron(2);
listt.Insertfron(3);
listt.Print();
listt.Insertback(4);
listt.Print();
return 0;
}
You are not initializing head to NULL to indicate an empty list, so ``head` will have a random garbage value, and thus all of your methods exhibit undefined behavior.
Once that is fixed, your while loops in both Print() and Insertback() are buggy, as they are not account for head being NULL when the list is empty.
Also, you are leaking every node you create. You need to add a destructor to free the nodes when you are done using the list.
With that said, try something more like this instead:
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
class lst
{
public:
lst();
~lst();
void Insertfron(int x);
void Print();
void Insertback(int x);
private:
Node* head;
};
lst::lst()
: head(NULL)
{
}
lst::~lst()
{
while (head != NULL)
{
Node *next = head->next;
delete head;
head = next;
}
}
void lst::Insertfron(int x)
{
Node* temp = new Node;
temp->data = x;
temp->next = head;
head = temp;
}
void lst::Print()
{
Node* temp = head;
while (temp != NULL)
{
cout << temp->data << ' ';
temp = temp->next;
}
cout << endl;
}
void lst::Insertback(int x)
{
Node* backinst = new Node;
backinst->data = x;
backinst->next = NULL;
if (head == NULL)
{
head = backinst;
}
else
{
Node* temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = backinst;
}
}
int main()
{
lst listt;
listt.Insertfron(1);
listt.Insertfron(2);
listt.Insertfron(3);
listt.Print();
listt.Insertback(4);
listt.Print();
return 0;
}
That being said, Insertback() can be simplified to avoid the extra if by using an extra level of pointer indirection:
void lst::Insertback(int x)
{
Node **temp = &head;
while (*temp != NULL)
{
temp = &((*temp)->next);
}
Node* backinst = new Node;
backinst->data = x;
backinst->next = NULL;
*temp = backinst;
}

Linked list with nodes

I am trying to make a linked list and test it in c++ using nodes. I create six nodes and then I print them forward and backwards like this:
main.cpp
#include "LinkedList.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void TestAddHead();
int main()
{
TestAddHead();
system("pause");
return 0;
}
void TestAddHead()
{
cout << "Testing AddHead()" << endl;
LinkedList<int> data;
for (int i = 0; i < 12; i += 2)
data.AddHead(i);
cout << "Node count: " << data.NodeCount() << endl;
cout << "Print list forward:" << endl;
data.PrintForward();
cout << "Print list in reverse:" << endl;
data.PrintReverse();
}
LinkedList.h
#pragma once
#include <iostream>
#include <vector>
#include <array>
#include <stdexcept>
#include <string>
using namespace std;
template<typename T>
class LinkedList
{
public:
struct Node
{
T data_;
Node* next;
Node* previous;
};
void PrintForward() const;
void PrintReverse() const;
unsigned int NodeCount() const;
void AddHead(const T &data);
LinkedList();
LinkedList(const LinkedList<T> &list);
~LinkedList();
private:
Node* head = new Node;
Node* tail = new Node;
unsigned int count = 0;
};
template<typename T>
LinkedList<T>::LinkedList()
{
}
template<typename T>
LinkedList<T>::LinkedList(const LinkedList<T> &list)
{
}
template<typename T>
LinkedList<T>::~LinkedList()
{
}
template<typename T>
void LinkedList<T>::AddHead(const T &data)
{
Node* newNode = new Node;
newNode->data_ = data;
if (count == 0)
{
head = newNode;
tail = newNode;
head->next = nullptr;
head->previous = nullptr;
}
else
{
newNode->next = head;
head->previous = newNode;
head = newNode;
}
count = count + 1;
}
template<typename T>
void LinkedList<T>::PrintForward() const
{
Node* currentNode = head;
while (currentNode != nullptr)
{
cout << currentNode->data_ << endl;
currentNode = currentNode->next;
}
}
template<typename T>
void LinkedList<T>::PrintReverse() const
{
Node* currentNode2 = tail;
while (currentNode2 != nullptr)
{
cout << currentNode2->data_ << endl;
currentNode2 = currentNode2->previous;
}
}
template<typename T>
unsigned int LinkedList<T>::NodeCount() const
{
return count;
}
this should be the output of the program:
Testing AddHead()
Node count: 6
Print list forward:
10
8
6
4
2
0
Print list in reverse:
0
2
4
6
8
10
The program works and gives me the correct output but the problem is that it just crashes when it reaches the "10" at the bottom of the program and I don't know why, can anyone tell me why is this happening and a possible way to fix it? thank you
Your immediate problem, you never set the new node previous pointer to nullptr ( a problem that honestly should be rectified by a better constructed loop and/or a proper constructor for Node). Regardless, here...
template<typename T>
void LinkedList<T>::AddHead(const T &data)
{
Node* newNode = new Node;
newNode->data_ = data;
if (count == 0)
{
head = newNode;
tail = newNode;
head->next = nullptr;
head->previous = nullptr;
}
else
{
newNode->next = head;
newNode->previous = nullptr; // ADD THIS
head->previous = newNode;
head = newNode;
}
count = count + 1;
}
There are still several things wrong in this: memory leaks, empty copy-ctor and destructor, etc, but the above is the root of the current evil. That line could also be:
newNode->previous = head->previous;
but frankly that just confuses what you're doing. You're always landing your new nodes at the head of the list, so the previous member of said-same will always be nullptr (at least until you start studying circular lists).

Single linked list, practice implementation

I am preparing for some interviews and I trying to just write a basic single linked list quickly. The code compiles fine but nothing seems to print and I am not sure why.
This is what I did:
#include <iostream>
#include <memory>
#include <utility>
struct Node {
int data;
std::unique_ptr<Node> next = nullptr;
Node(const int& x, std::unique_ptr<Node>&& p = nullptr)
: data(x)
, next(std::move(p)) {}
};
std::unique_ptr<Node> head;
Node* tail;
void print() {
auto temp = head.get();
while (temp) {
std::cout << temp->data << " ";
temp = temp->next.get();
}
std::cout << "\t";
}
void push_back(const int& theData) {
std::unique_ptr<Node> newNode = std::make_unique<Node>(theData);
if (!head) {
newNode = std::move(head);
tail = head.get();
}
else {
tail->next = std::move(newNode);
tail = tail->next.get();
}
}
int main() {
head = nullptr;
tail = nullptr;
push_back(2);
push_back(4);
push_back(6);
print();
std::cin.get();
}
This should print 2 4 6 but it does not print anything. Any idea why?
You are not updaing your head in push_back(). Instead of
if (!head) { newNode = std::move(head); ... }
you should be doing
if (!head) {head = std::move(newNode); ... }

Simple linked list in C++

I am about to create a linked that can insert and display until now:
struct Node {
int x;
Node *next;
};
This is my initialisation function which only will be called for the first Node:
void initNode(struct Node *head, int n){
head->x = n;
head->next = NULL;
}
To add the Node, and I think the reason why my linked list isn't working correct is in this function:
void addNode(struct Node *head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
My main function:
int _tmain(int argc, _TCHAR* argv[])
{
struct Node *head = new Node;
initNode(head, 5);
addNode(head, 10);
addNode(head, 20);
return 0;
}
Let me run the program as I think it works. First I initialise the head Node as a Node like this:
head = [ 5 | NULL ]
Then I add a new node with n = 10 and pass head as my argument.
NewNode = [ x | next ] where next points at head. And then I change the place where head is pointing to NewNode, since NewNode is the first Node in LinkedList now.
Why isn't this working? I would appreciate any hints that could make me move in the right direction. I think LinkedList is a bit hard to understand.
When I'm printing this, it only returns 5:
This is the most simple example I can think of in this case and is not tested. Please consider that this uses some bad practices and does not go the way you normally would go with C++ (initialize lists, separation of declaration and definition, and so on). But that are topics I can't cover here.
#include <iostream>
using namespace std;
class LinkedList{
// Struct inside the class LinkedList
// This is one node which is not needed by the caller. It is just
// for internal work.
struct Node {
int x;
Node *next;
};
// public member
public:
// constructor
LinkedList(){
head = NULL; // set head to NULL
}
// destructor
~LinkedList(){
Node *next = head;
while(next) { // iterate over all elements
Node *deleteMe = next;
next = next->next; // save pointer to the next element
delete deleteMe; // delete the current entry
}
}
// This prepends a new value at the beginning of the list
void addValue(int val){
Node *n = new Node(); // create new Node
n->x = val; // set value
n->next = head; // make the node point to the next node.
// If the list is empty, this is NULL, so the end of the list --> OK
head = n; // last but not least, make the head point at the new node.
}
// returns the first element in the list and deletes the Node.
// caution, no error-checking here!
int popValue(){
Node *n = head;
int ret = n->x;
head = head->next;
delete n;
return ret;
}
// private member
private:
Node *head; // this is the private member variable. It is just a pointer to the first Node
};
int main() {
LinkedList list;
list.addValue(5);
list.addValue(10);
list.addValue(20);
cout << list.popValue() << endl;
cout << list.popValue() << endl;
cout << list.popValue() << endl;
// because there is no error checking in popValue(), the following
// is undefined behavior. Probably the program will crash, because
// there are no more values in the list.
// cout << list.popValue() << endl;
return 0;
}
I would strongly suggest you to read a little bit about C++ and Object oriented programming. A good starting point could be this: http://www.galileocomputing.de/1278?GPP=opoo
EDIT: added a pop function and some output. As you can see the program pushes 3 values 5, 10, 20 and afterwards pops them. The order is reversed afterwards because this list works in stack mode (LIFO, Last in First out)
You should take reference of a head pointer. Otherwise the pointer modification is not visible outside of the function.
void addNode(struct Node *&head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
I'll join the fray. It's been too long since I've written C. Besides, there's no complete examples here anyway. The OP's code is basically C, so I went ahead and made it work with GCC.
The problems were covered before; the next pointer wasn't being advanced. That was the crux of the issue.
I also took the opportunity to make a suggested edit; instead of having two funcitons to malloc, I put it in initNode() and then used initNode() to malloc both (malloc is "the C new" if you will). I changed initNode() to return a pointer.
#include <stdlib.h>
#include <stdio.h>
// required to be declared before self-referential definition
struct Node;
struct Node {
int x;
struct Node *next;
};
struct Node* initNode( int n){
struct Node *head = malloc(sizeof(struct Node));
head->x = n;
head->next = NULL;
return head;
}
void addNode(struct Node **head, int n){
struct Node *NewNode = initNode( n );
NewNode -> next = *head;
*head = NewNode;
}
int main(int argc, char* argv[])
{
struct Node* head = initNode(5);
addNode(&head,10);
addNode(&head,20);
struct Node* cur = head;
do {
printf("Node # %p : %i\n",(void*)cur, cur->x );
} while ( ( cur = cur->next ) != NULL );
}
compilation: gcc -o ll ll.c
output:
Node # 0x9e0050 : 20
Node # 0x9e0030 : 10
Node # 0x9e0010 : 5
Below is a sample linkedlist
#include <string>
#include <iostream>
using namespace std;
template<class T>
class Node
{
public:
Node();
Node(const T& item, Node<T>* ptrnext = NULL);
T value;
Node<T> * next;
};
template<class T>
Node<T>::Node()
{
value = NULL;
next = NULL;
}
template<class T>
Node<T>::Node(const T& item, Node<T>* ptrnext = NULL)
{
this->value = item;
this->next = ptrnext;
}
template<class T>
class LinkedListClass
{
private:
Node<T> * Front;
Node<T> * Rear;
int Count;
public:
LinkedListClass();
~LinkedListClass();
void InsertFront(const T Item);
void InsertRear(const T Item);
void PrintList();
};
template<class T>
LinkedListClass<T>::LinkedListClass()
{
Front = NULL;
Rear = NULL;
}
template<class T>
void LinkedListClass<T>::InsertFront(const T Item)
{
if (Front == NULL)
{
Front = new Node<T>();
Front->value = Item;
Front->next = NULL;
Rear = new Node<T>();
Rear = Front;
}
else
{
Node<T> * newNode = new Node<T>();
newNode->value = Item;
newNode->next = Front;
Front = newNode;
}
}
template<class T>
void LinkedListClass<T>::InsertRear(const T Item)
{
if (Rear == NULL)
{
Rear = new Node<T>();
Rear->value = Item;
Rear->next = NULL;
Front = new Node<T>();
Front = Rear;
}
else
{
Node<T> * newNode = new Node<T>();
newNode->value = Item;
Rear->next = newNode;
Rear = newNode;
}
}
template<class T>
void LinkedListClass<T>::PrintList()
{
Node<T> * temp = Front;
while (temp->next != NULL)
{
cout << " " << temp->value << "";
if (temp != NULL)
{
temp = (temp->next);
}
else
{
break;
}
}
}
int main()
{
LinkedListClass<int> * LList = new LinkedListClass<int>();
LList->InsertFront(40);
LList->InsertFront(30);
LList->InsertFront(20);
LList->InsertFront(10);
LList->InsertRear(50);
LList->InsertRear(60);
LList->InsertRear(70);
LList->PrintList();
}
Both functions are wrong. First of all function initNode has a confusing name. It should be named as for example initList and should not do the task of addNode. That is, it should not add a value to the list.
In fact, there is not any sense in function initNode, because the initialization of the list can be done when the head is defined:
Node *head = nullptr;
or
Node *head = NULL;
So you can exclude function initNode from your design of the list.
Also in your code there is no need to specify the elaborated type name for the structure Node that is to specify keyword struct before name Node.
Function addNode shall change the original value of head. In your function realization you change only the copy of head passed as argument to the function.
The function could look as:
void addNode(Node **head, int n)
{
Node *NewNode = new Node {n, *head};
*head = NewNode;
}
Or if your compiler does not support the new syntax of initialization then you could write
void addNode(Node **head, int n)
{
Node *NewNode = new Node;
NewNode->x = n;
NewNode->next = *head;
*head = NewNode;
}
Or instead of using a pointer to pointer you could use a reference to pointer to Node. For example,
void addNode(Node * &head, int n)
{
Node *NewNode = new Node {n, head};
head = NewNode;
}
Or you could return an updated head from the function:
Node * addNode(Node *head, int n)
{
Node *NewNode = new Node {n, head};
head = NewNode;
return head;
}
And in main write:
head = addNode(head, 5);
The addNode function needs to be able to change head. As it's written now simply changes the local variable head (a parameter).
Changing the code to
void addNode(struct Node *& head, int n){
...
}
would solve this problem because now the head parameter is passed by reference and the called function can mutate it.
head is defined inside the main as follows.
struct Node *head = new Node;
But you are changing the head in addNode() and initNode() functions only. The changes are not reflected back on the main.
Make the declaration of the head as global and do not pass it to functions.
The functions should be as follows.
void initNode(int n){
head->x = n;
head->next = NULL;
}
void addNode(int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode->next = head;
head = NewNode;
}
I think that, to make sure the indeep linkage of each node in the list, the addNode method must be like this:
void addNode(struct node *head, int n) {
if (head->Next == NULL) {
struct node *NewNode = new node;
NewNode->value = n;
NewNode->Next = NULL;
head->Next = NewNode;
}
else
addNode(head->Next, n);
}
Use:
#include<iostream>
using namespace std;
struct Node
{
int num;
Node *next;
};
Node *head = NULL;
Node *tail = NULL;
void AddnodeAtbeggining(){
Node *temp = new Node;
cout << "Enter the item";
cin >> temp->num;
temp->next = NULL;
if (head == NULL)
{
head = temp;
tail = temp;
}
else
{
temp->next = head;
head = temp;
}
}
void addnodeAtend()
{
Node *temp = new Node;
cout << "Enter the item";
cin >> temp->num;
temp->next = NULL;
if (head == NULL){
head = temp;
tail = temp;
}
else{
tail->next = temp;
tail = temp;
}
}
void displayNode()
{
cout << "\nDisplay Function\n";
Node *temp = head;
for(Node *temp = head; temp != NULL; temp = temp->next)
cout << temp->num << ",";
}
void deleteNode ()
{
for (Node *temp = head; temp != NULL; temp = temp->next)
delete head;
}
int main ()
{
AddnodeAtbeggining();
addnodeAtend();
displayNode();
deleteNode();
displayNode();
}
In a code there is a mistake:
void deleteNode ()
{
for (Node * temp = head; temp! = NULL; temp = temp-> next)
delete head;
}
It is necessary so:
for (; head != NULL; )
{
Node *temp = head;
head = temp->next;
delete temp;
}
Here is my implementation.
#include <iostream>
using namespace std;
template< class T>
struct node{
T m_data;
node* m_next_node;
node(T t_data, node* t_node) :
m_data(t_data), m_next_node(t_node){}
~node(){
std::cout << "Address :" << this << " Destroyed" << std::endl;
}
};
template<class T>
class linked_list {
public:
node<T>* m_list;
linked_list(): m_list(nullptr){}
void add_node(T t_data) {
node<T>* _new_node = new node<T>(t_data, nullptr);
_new_node->m_next_node = m_list;
m_list = _new_node;
}
void populate_nodes(node<T>* t_node) {
if (t_node != nullptr) {
std::cout << "Data =" << t_node->m_data
<< ", Address =" << t_node->m_next_node
<< std::endl;
populate_nodes(t_node->m_next_node);
}
}
void delete_nodes(node<T>* t_node) {
if (t_node != nullptr) {
delete_nodes(t_node->m_next_node);
}
delete(t_node);
}
};
int main()
{
linked_list<float>* _ll = new linked_list<float>();
_ll->add_node(1.3);
_ll->add_node(5.5);
_ll->add_node(10.1);
_ll->add_node(123);
_ll->add_node(4.5);
_ll->add_node(23.6);
_ll->add_node(2);
_ll->populate_nodes(_ll->m_list);
_ll->delete_nodes(_ll->m_list);
delete(_ll);
return 0;
}
link list by using node class and linked list class
this is just an example not the complete functionality of linklist, append function and printing a linklist is explained in the code
code :
#include<iostream>
using namespace std;
Node class
class Node{
public:
int data;
Node* next=NULL;
Node(int data)
{
this->data=data;
}
};
link list class named as ll
class ll{
public:
Node* head;
ll(Node* node)
{
this->head=node;
}
void append(int data)
{
Node* temp=this->head;
while(temp->next!=NULL)
{
temp=temp->next;
}
Node* newnode= new Node(data);
// newnode->data=data;
temp->next=newnode;
}
void print_list()
{ cout<<endl<<"printing entire link list"<<endl;
Node* temp= this->head;
while(temp->next!=NULL)
{
cout<<temp->data<<endl;
temp=temp->next;
}
cout<<temp->data<<endl;;
}
};
main function
int main()
{
cout<<"hello this is an example of link list in cpp using classes"<<endl;
ll list1(new Node(1));
list1.append(2);
list1.append(3);
list1.print_list();
}
thanks ❤❤❤
screenshot https://i.stack.imgur.com/C2D9y.jpg

Why does my linked list code result in link errors?

I'm new to linklist, and i'm having a tough time with it. I'm trying to display some values that i've appended to the nodes, But i keep getting linkerror messages. Here is what I have so far.
LinkList.h
-
#ifndef LINKLIST_H
#define LINKLIST_H
class LinkList
{
private:
struct ListNode
{
int value;
ListNode *next;
};
ListNode *head;
public:
LinkList();
void insertNode(int);
void deleteNode(int);
void appendNode(int);
void display() const;
//~LinkList();
};
#endif
Impl.cpp
-
#include <iostream>
#include "LinkList.h"
using namespace std;
void LinkList::appendNode(int num)
{
ListNode * newNode;
ListNode * nodePtr;
newNode = new ListNode;
newNode->value = num;
newNode->next = NULL;
if(!head)
{
head = newNode;
head->value = num;
head->next=NULL;
}
else
{
nodePtr = head;
while(nodePtr->next!=NULL)
nodePtr = nodePtr->next;
newNode = new ListNode;
newNode->value = num;
newNode->next = NULL;
nodePtr->next = newNode;
}
}
void LinkList::display() const
{
ListNode *nodePtr;
nodePtr = head;
while (nodePtr != NULL)
{
cout << nodePtr->value << endl;
nodePtr = nodePtr->next;
}
}
LinkList::LinkList()
{
head = NULL;
}
main.cpp
-
#include <iostream>
#include "LinkList.h"
using namespace std;
int main()
{
LinkList mine;
mine.appendNode(6);
mine.appendNode(9);
mine.appendNode(11);
mine.display();
return 0;
}
I fixed some of the initial problems but the program just crashes when it runs and i'm not sure why
I'm not sure what the problems is, any help would be greatly appreciated.
You declared a LinkList constructor, and a destructor, but you did not define them:
LinkList::LinkList() : head(NULL)
{
}
LinkList::~LinkList()
{
// delete your memory here...
}