Making template type LinkedList - c++

i have recently started studying linkedlist in c++. Although i am finding it pretty confusing but i made some functions to insert and delete and element from the linkedlist.
The program worked fine with int data type. But i want to create a linkedlist of template type and i cannot understand how to do it.
I have tried to create a function to insert the node at the first position of link list but it gives me errors like access specifier needed before node etc ...
#include <iostream>
#include<conio.h>
using namespace std;
template<class T>
class node
{
public:
T data;
node *next;
};
template<class T>
class linklist
{
public:
node <int>*head;
linklist()
{
head = NULL;
}
bool Is_Empty(node <T>*ptr)
{
if(ptr==NULL)
{
return true;
}
return false;
}
void insert_at_head(T num)
{
if(Is_Empty(head))
{
node <T>*temp = new node; // error is on this line. it says access specifier needed before node.
temp->data = num;
head = temp;
temp->next = NULL;
}
else
{
node *temp = new node;
temp->data = num;
head = temp;
temp->next = head->next;
}
}
void show_list(node <T>*ptr)
{
cout<<"\nElements in the List are : ";
while(ptr!=NULL)
{
cout<<ptr->data<<" ";
ptr = ptr->next;
}
}
};
int main()
{
cout << "Hello world!" << endl;
getch()
}

Related

I read the input number with getchar(), why is the number reversed in the linked list?

I typed 1234, but the list has 4,3,2,1 in it. I suspect the problem is getchar() itself, or a function in the class, but I have no way to find out.
The link class is responsible for some linked list operations, such as deletion, insertion, etc., while the node class is responsible for creating and assigning nodes.
The createlist class is responsible for the creation of the linked list, which is the main source of the problem. I wrote the debug statement in it, so you can run it and see the results for yourself
using namespace std;
class Node
{
public:
int data;
Node *next;
Node()
{
next = nullptr;
}
Node(int data)
{
this->data = data;
}
Node(const Node &temp)
{
this->data = temp.data;
}
};
class Link
{
public:
Node *head;
int length = 0;
Link()
{
head = new Node();
}
~Link()
{
while (head != nullptr)
{
Node *p = head->next;
free(head);
head = p;
}
}
void insert(const Node &cache)
{
Node *temp = new Node(cache);
temp->next = head->next;
head->next = temp;
length++;
}
};
void Creatlist(Link &link)
{
char cache;
while (1)
{
cache = getchar();
if (cache == '\n')
break;
link.insert(Node(cache - '0'));
cout << cache << " ";
}
cout<<endl;
Node *p = link.head->next;
cout << "in the linklist:";
while (p != nullptr)
{
cout << p->data << " ";
p = p->next;
}
}
int main()
{
Link link;
cout<<"inut numbers:"<<endl;
Creatlist(link);
}```
With the insert you inserted to the FRONT of the list. So you had "1", then "2->1" ... If you want to insert to the end, don't insert at the head, but hake a Node* tail in the class Link and an insert_end function as
//...
Node* temp;
void insert_end(const Node &cache){
Node *temp = new Node(cache);
tail->next=temp;
tail=tail->next;
length++;
}
Alsoin the constructor set tail=head

How can I have a linked-list using class?

I'm trying to write a linked-list using class and I want it to have a specific format.
For example if I have three data called p1,p2 and p3 and a linked-list called list; I want to put them in order like blow.
list.insert(p1).insert(p2).insert(p3);
I tried to return the object, but didn't work.
Here's my code.
#include<iostream>
using namespace std;
class linked_list {
public:
int *head;
linked_list();
~linked_list();
linked_list insert(int data);
};
linked_list::linked_list()
{
head = NULL;
}
linked_list::~linked_list()
{
int *temp;
int *de;
for (temp = head;temp != NULL;) {
de = temp->next;
delete temp;
temp = de;
}
delete temp;
//delete de;
}
linked_list linked_list::insert(int data)
{
int *temp;
temp = new int;
*temp = data;
temp->next = NULL;
if (head == NULL) {
head = temp;
}
else {
int* node = head;
while (node->next != NULL) {
node = node->next;
}
node->next = temp;
// delete node;
}
//delete temp;
return *this;
}
int main(){
linked_list l1;
int p1,p2,p3;
l1.insert(p1).insert(p2).insert(p3);
return 0;}
#Jarod42 got your answer, despite all the buggy things around, what you want is something like this.
The function you want to chain must return a reference to your current object instance.
Here is a Foo class that change its _data member and chain multiple time.
#include <iostream>
class Foo
{
private:
int _data;
public:
Foo(int data) : _data(data) {}
~Foo()
{
}
// change the value of data then return a reference to the current Foo instance
Foo &changeData(int a)
{
_data = a;
return *this;
}
void printData()
{
std::cout << _data << std::endl;
}
};
int main()
{
Foo f(1);
f.changeData(2).changeData(3);
f.printData();
}
Note that I'm returning Foo& from the function I'm chaining, that's the little trick that is missing from yours.
Hope it helped you :)

Singly Linked List assign issue (nullptr)

what's wrong with this simple Linked List ?
// linked_lst1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class Node
{
int data;
Node* next;
friend class LinkedList;
};
class LinkedList
{
private:
Node* s;
public:
LinkedList() : s(NULL)
{};
void add(int x)
{
Node* s1 = new Node();
s1 = s;
if (!s1)
{
s->data = x;
return;
}
while (s1->next)
s1 = s1->next;
Node* temp = new Node;
temp->data = x;
s1->next = temp;
temp->next = NULL;
}
void showList()
{
Node* s1 = new Node;
s1 = s;
while (s1)
{
cout << s1->data << " ";
s1 = s1->next;
}
}
};
Here is main section :
int main()
{
LinkedList list;
list.add(3);
list.showList();
return 0;
}
I think there is an assign issue in s->data = x;, but I don't know how to solve it...
Notice that this is just an educational simple code and I don't want to use templates etc.
I think, I got what was wrong.
You make a new node and then immediately overwrite s1 to point to whatever s was pointing to -- you lose all access to the newly created node.

how can i get the front or top element of a vector queue?

I didn't put the full code because it was very long and i only need help with the small portion which is the **** area. i can't seem to use front() or top() to get the top element of the queue. I tried making top() function List keep getting error : 1) class List has no memeber named 'top' which means i don't have a function top in List, when i make it it says 2) no match for 'operator=' in printer_cpu[i] = SList::top() with T=PCB]()'
template <class T>
class node{
public:
T data;
node *next;
};
template <class T>
class List{
node<T> *head;
node<T> *tail;
public:
List()
{
head = tail = NULL;
}
bool isEmpty()
{
if(head == NULL) return true;
else return false;
}
void enqueue(T new_data){
node<T> *temp = new node<T>;
temp->data = new_data;
temp->next = NULL;
if(isEmpty()){
head = temp;
tail = temp;
}
else{
tail->next = temp;
tail = temp;
}
}
void dequeue(){
if(isEmpty())
{
cout << "The list is already empty" << endl;
}
node<T>* temp;
if(head == tail){
temp->data=head->data;
delete head;
head = tail = NULL;
}
else{
temp->data = head->data;
head = head->next;
delete temp;
}
}
node<T> top() // need help here ****
{
return head;
}
void display(){
node<T> *current = head;
while(current != NULL){
cout << current->data << endl;
current = current->next;
}
}
};
struct PCB
{
int ProcessID;
int ProcessorSize;
int priority;
string name;
};
typedef List<PCB> printing;
typedef List<PCB> disk;
void gen(vector<printing> &printer_queue,string printer_name[], int printers)
{
for(int i = 0; i < printers; i++)
{
int num = i+1;
ostringstream convert;
convert << num;
printer_name[i] = "p" + convert.str();
printer_queue.push_back(printing());
}
int main()
{
int numOfPrinter = 5;
string interrupt;
cin >> interrupt;
PCB cpu;
PCB printer_cpu[numOfPrinter];
string printer_name[numOfPrinter];
vector<printing> PQ;
gen(PQ,printer_name,numOfPrinter);
for(int i = 0; i < numOfPrinter; i++)
{
if(interrupt == printer_name[i])
{
cout << "Enter a name for this printer file: " << endl;
cin >> cpu.name;
PQ[i].enqueue(cpu);
printer_cpu[i] = PQ[i].top(); //need help here ****
}
}
}
It looks like you're missing an asterisk, because you need to return of type pointer, because that's what head is.
You should have
node<T> * top()
{
...
}
You also need to overload the = operator, because you are trying to compare type PCB with type node *.
Well, I compile your code successfully after correcting some mistakes.
I didn't meet class List has no memeber named 'top' problem.
Then your top() function returns the value of head, so you should change it to: node<T>* top() because head is a pointer to node<T>.
And the reason you got no match for 'operator=' error is that printer_cpu[i]'s type is PCB while PQ[i].top()'s type should be node<T>*
I have also found that the code you post lacks a } just before int main().

Linked list class

The purpose of my program is to read in data from a file and build a linked list with this data and then deallocate all the nodes used.
the program also needs to print out the address of nodes after they are created and then after that they are deleted
#include <iostream>
#include <string>
#include <fstream>
#include "BigHero.h"
using namespace std;
// Linked List Struct
struct Node{
BigHero data;
Node* Next;
};
// Funtion Prototypes
int countHeros(string,int&);
void createList(BigHero,int,Node*&,Node*&,Node*&);
void printList(Node*,Node*,Node*);
void deallocateList(Node*&,Node*&,Node*&);
int main()
{
// Program Variables
Node* head;
Node* currentPtr;
Node* newNodePtr;
string Filename = "ola5party.dat"; // File string varible
int charNumber = 0; // variable to hold number of Heroes
int i = 0; // Loop control varible
countHeros(Filename,charNumber); // Function call used to count number of Heros
ifstream inFile;
inFile.open(Filename.c_str());
if(!inFile){
cout << "Error in opening file" << endl;
return 0;
}
BigHero Hero;
while(inFile)
{
inFile >> Hero;
createList(Hero,charNumber,head,currentPtr,newNodePtr);
}
printList(head,currentPtr,newNodePtr);
deallocateList(head,currentPtr,newNodePtr);
inFile.close();
return 0;
}
int countHeros(string Filename,int& charNumber)
{
ifstream inFile;
inFile.open(Filename.c_str());
string aLineStr;
while (getline(inFile, aLineStr))
{
if (!aLineStr.empty())
charNumber++;
}
inFile.close();
return charNumber;
}
void createList(BigHero Hero, int charNumber,Node*& head, Node*& currentPtr, Node*& newNodePtr)
{
head = new Node;
head->data =Hero;
currentPtr = head;
newNodePtr = new Node;
cout << "Allocated # " << newNodePtr << endl;
newNodePtr->data = Hero;
currentPtr->Next = newNodePtr;
currentPtr = newNodePtr;
}
void printList(Node* head, Node* currentPtr, Node* newNodePtr)
{
if(head != NULL)
{
currentPtr = head;
while(currentPtr->Next != NULL)
{
cout << currentPtr->data << endl;
currentPtr = currentPtr->Next;
}
}
}
void deallocateList(Node*& head ,Node*& currentPtr,Node*& newNodePtr)
{
if( head != NULL)
{
currentPtr = head;
while( head -> Next != NULL)
{
head = head->Next;
cout << "Deleting # " << head << endl;
delete currentPtr;
currentPtr = head;
}
delete head;
head = NULL;
currentPtr = NULL;
}
}
the program like this runs without errors, but here is the problem it will input all the information required but since i only have one variable hero class it is constantly replacing the information.
i tried to make a class array (example hero[i]) but cant seem to get it right and am not even sure if that is the solution. Everything is fine but i cant get the desired number of class object and i always end up with one class
this is my desired output but i only get one class object
Allocated#0x8722178
Allocated#0x87221d0
Allocated#0x8722210
Allocated#0x8722230
Allocated#0x8722288
Allocated#0x87222c8
Hero:MacWarrior­Level134,(34,16,48)­Exp:13425
Hero:LinuxMage­Level149,(24,54,21)­Exp:14926
Hero:PCBard­Level122,(18,32,17)­Exp:12221
Hero:PythonThief­Level90,(24,18,61)­Exp:9001
Hero:CplusPaladin­Level159,(31,38,29)­Exp:15925
Deleting#0x8722178
Deleting#0x87221d0
Deleting#0x8722210
Deleting#0x8722230
Deleting#0x8722288
Deleting#0x87222c8
It seems you have misunderstood the basic idea behind a link listed. You are not supposed to overwrite head again and again when adding element. head shall only be changed when the list is empty.
Try something like this:
struct Node
{
BigHero data;
Node* next;
};
void addNewNode(Node*& head, ....)
{
if (head == nullptr)
{
// List empty so add new node as head
head = new Node;
head->next = nullptr;
return;
}
// Find last element in list (performance can be improved with a tail*)
Node* temp = head;
while (temp->next != nullptr) temp = temp->next;
// Add new element to end of list
temp->next = new Node;
temp->next->next = nullptr
return;
}
int main()
{
Node* head = nullptr;
addNewNode(head, ....);
return 0;
}
For performance it is often good to have a tail-pointer also.
Further you should not define head in main() but make a class/struct for it and put the relevant functions in the class. Like:
struct Node
{
BigHero data;
Node* next;
};
class ListOfNode
{
public:
ListOfNode() : head(nullptr), size(0) {}
~ListOfNode()
{
// Delete all nodes
}
void addNewNode(....)
{
// ....
++size;
}
size_t size() { return size; }
private:
Node* head; // Optional: Add a tail* for better performance
size_t size;
};
int main()
{
ListOfNode list;
list.addNewNode(....);
cout << list.size() << endl;
return 0;
}