Here's a program which takes student name and registration number from user and stores it in a doubly linkedlist. And I'm inserting nodes at the end . But there is a logical error in while loop. It takes Name and Reg. Number but then stops.Please Help
class dlist{
struct node{
string name;
string regno;
node *next;
node *prev;
};
public:
node *head,*tail;
void insert(string,string);
void search(string);
};
void dlist::insert(string nn, string r)
{
node *ptr,*newNode;
tail=head;
newNode= new node;
newNode->name=nn;
newNode->regno=r;
newNode->next=NULL;
newNode->prev=NULL;
if(!head)
{
head=newNode;
tail=head;
}
else
{
ptr = head;
while(ptr)
ptr=ptr->next;
newNode->next=tail;
newNode->prev=ptr;
ptr->next-newNode;
}
}
void dlist::search(string n){
node *ptr;
ptr=head;
while(ptr->next!=NULL)
{
if(ptr->name==n)
cout<<"Name found..." <<ptr->name<<endl;
ptr=ptr->next;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
dlist dl;
string nn;
string n;
string r;
for(int i=0;i<5;i++)
{
cout<<"Enter student's name: ";
cin>>nn;
cout<<"Enter student's Registration Number: ";
cin>>r;
dl.insert(nn,r);
}
cout<<"Enter a name to search: ";
cin>>n;
dl.search(n);
}
You are having problems using the tail pointer. I've improved your code below and added comments explaining what I did. If you have any more questions about what I did, ask in the comments and I'll be happy to clarify.
#include <tchar.h>
#include <string>
#include <iostream>
class dlist {
struct node {
string name;
string regno;
node* next;
node* prev;
};
public:
node* head, * tail;
void insert(string, string);
void search(string);
/**
* You're using classes, so go ahead and provide a definition for the
* constructor you're using. This one will initialize head and tail to
* be null
*/
dlist() : head(NULL), tail(NULL) {}
/**
* It's important to delete any memory you allocate so that you don't create a memory
* leak.
*/
virtual ~dlist() {
while (head) {
node* deleteMe = head;
head = head->next;
delete deleteMe;
}
}
};
void dlist::insert(string nn, string r) {
// there is no good reason to set tail=head at this time.
// and you don't need a ptr, that's why we have tail.
node* newNode = new node;
newNode->name = nn;
newNode->regno = r;
// no need to set newNode->prev now, as that will be taken care of later
newNode->next = NULL;
// if we don't have any nodes yet, we need to set head = newNode
// and make head point to tail, which is also head.
if (!head) {
head = newNode;
tail = head;
head->next = tail;
tail->prev = head;
// head points to itself both ways
} else {
// we already have some nodes, so go ahead and
// set newNode to go right after tail, then set tail = newNode
// this will work even when head == tail
tail->next = newNode;
newNode->prev = tail;
tail = newNode;
}
}
void dlist::search(string n) {
// it's nice to assign variables when you declare them, when you can
node* ptr = head;
// basically the same as what you had, but we are checking in the case
// that tail has the node we want, which your code did not do.
while (ptr) {
if (ptr->name == n) {
cout << "Name found... " << ptr->name << endl;
}
ptr = ptr->next;
}
}
int _tmain(int argc, _TCHAR* argv[]) {
dlist dl;
string nn;
string n;
string r;
for (int i = 0; i < 5; i++) {
cout << "Enter student's name: ";
cin >> nn;
cout << nn << endl;
cout << "Enter student's Registration Number: ";
cin >> r;
cout << r << endl;
dl.insert(nn, r);
}
cout << "Enter a name to search: ";
cin >> n;
dl.search(n);
return 0;
}
Related
I have to dynamically allocate a list of robots for a school project. In an actual program, there will be other member functions that will require the list of names in order to perform certain functions.
As of right now, I just learned about this concept, and have tried really hard to put together some things I have seen online. The issue at the moment is that I can not tell if my list is properly being stored -- I am also getting wonky output when I try to call my display of list function.
Please help if you can. Also, I am happy to hear any tips for literally anything, as I am fairly new to programming.
class Node{
public:
std::string name_;
Node* next;
};
class linkedBotList{
public:
linkedBotList() {head = nullptr;} //constructor
~linkedBotList(){}; // destructure
void addNode();
void display();
private:
Node* head;
};
int main(int argc, const char * argv[]) {
linkedBotList* list = new linkedBotList();
int siz;
std::cout << "How many Robots?" << std::endl;
std::cout << "What are the names?" << std::endl;
std::cin >> siz;
for(int i = 0; i < siz; i++){
list->addNode();
}
delete list;
return 0;
}
void linkedBotList::addNode(){
std::string botName;
Node* newNode = new Node();
newNode->name_ = botName;
newNode->next = nullptr;
std::cin >> botName;
if(head == nullptr){
head = newNode;
}
else {
Node* temp = head; // head is not null
while(temp->next != nullptr){ // go until at the end of the list
temp = temp->next;
}
temp->next = new Node; // linking to new node
}
}
void linkedBotList::display() {
if (head == NULL) {
std::cout << "List is empty!" << std::endl;
}
else {
Node* temp = head;
while (temp != NULL) {
std::cout << "Made it to display funct.\n";
std::cout << temp->name_ << " ";
temp = temp->next;
}
std::cout << std::endl;
}
}
I did try a few things, like switching around my temp variable, and a few other re-assignments. Maybe someone can quickly spot the issue and help?
Your display function is fine.
The problem is that you have 2 logic flaws in addNode():
you are not storing strings in your list correctly. You are assigning botName to newNode->name_ before botName has been assigned a value. So all of your nodes have empty strings. Assigning botName afterwards will not update newNode->name_. 1
if the list is not empty, you iterate to the end of the list correctly 2, but then you assign a new blank node to temp->next instead of assigning your newNode that you already populated. And your Node constructor is not initializing the next member to nullptr, so you are creating a corrupted list, which will cause subsequent loops through the list to invoke undefined behavior.
Try this instead:
void linkedBotList::addNode(){
std::string botName;
std::cin >> botName; // <-- move up here
Node* newNode = new Node{botName, nullptr};
if (!head){
head = newNode;
}
else {
Node* temp = head;
while (temp->next){
temp = temp->next;
}
temp->next = newNode; // <-- linking to new node
}
}
Alternatively, you can eliminate the if like this:
void linkedBotList::addNode(){
std::string botName;
std::cin >> botName;
Node** temp = &head;
while (*temp){
temp = &((*temp)->next);
}
*temp = new Node{botName, nullptr};
}
1: A better design would be to have addNode() take in a string as an input parameter, and then move the cin call into your loop in main().
2: consider adding a tail member to your list to avoid having to loop on each addition.
Try this alternate design:
class Node{
public:
std::string name;
Node* next = nullptr;
};
class linkedBotList{
public:
linkedBotList() = default;
~linkedBotList();
void addNode(std::string name);
void display() const;
private:
Node* head = nullptr;
Node* tail = nullptr;
};
int main() {
linkedBotList list;
int siz;
std::string botName;
std::cout << "How many Robots?" << std::endl;
std::cin >> siz;
std::cout << "What are the names?" << std::endl;
for(int i = 0; i < siz; i++){
std::cin >> botName;
list.addNode(botName);
}
list.display();
return 0;
}
linkedBotList::~linkedBotList(){
Node *temp = head, *next;
while (temp) {
next = temp->next;
delete temp;
temp = next;
}
}
void linkedBotList::addNode(std::string name){
Node* newNode = new Node{name};
if (tail)
tail->next = newNode;
else
head = newNode;
tail = newNode;
}
void linkedBotList::display() const {
if (!head) {
std::cout << "List is empty!" << std::endl;
}
else {
Node* temp = head;
do {
std::cout << temp->name << " ";
temp = temp->next;
}
while (temp);
std::cout << std::endl;
}
}
I have no idea why display function is not displaying anything other than the first node's data. I've tried switching the While(p!=NULL) to while(p->next!= NULL but when I do that instead of only the first node's data displaying no data is being displayed.
#include <iostream>
using namespace std;
class Node {
public:
int no;
Node* next;
};
Node* createNode(int no1) {
Node* n = new Node();
n->no = no1;
n->next = NULL;
return n;
}
void addValue(int x, Node** head) {
//insert first node into linked list
Node* n = createNode(x),*p = *head;
if (*head == NULL) {
*head = n;
}
//insert second node onwards into linked list
else {
while (p->next!= NULL) {
p->next = n;
p = p->next;
}
}
}
void display(Node *head) {
Node* temp = head;
// temp is equal to head
while (temp->next!=NULL) {
cout << temp->no;
temp = temp->next;
}
}
int main() {
int num; char choice;
Node* head = NULL;
do {
cout << "Enter a number : ";
cin >> num;
addValue(num,&head);
cout << "Enter [Y] to add another number : ";
cin >> choice;
} while (choice == 'Y');
cout << "List of existing record : ";
display(head);
return 0;
}
I've tried changing the contents fo the else while loop in the addRecord function to p = p->next; p->next = n; in that order to no avail.
In the while loop, it should be
while (p->next!= NULL) {
p = p->next;
}
p->next = n;
Traverse until the end of linked list is reached and then, add the new entry.
I was writing a code for inserting a node in the beginning of a linked list, but i'm not able to recognize why the function is not adding the data .
void insert(Node* head) {
Node* n = new Node();
cout << "Enter the data to be added in beggining";
cin >> n->data;
n->next = head;
head = n;
}
Full Source Code :
#include<iostream>
using namespace std;
class Node; //Forward Declaration
int create(Node*);
void insert(Node*); //Function Prototyping
void show(Node*);
class Node {
public:
int data;
Node* next;
};
int main() {
Node* head;
head = new Node();
create(head);
insert(head);
show(head);
return 0;
}
//Fucntion to create a list
int create(Node* n) {
char c;
cout << "Enter Data to be stored" << endl;
cin >> n->data;
cout << "Press 0 to exit" << endl;
cin >> c;
if (c == '0') {
n->next = NULL;
return 0;
}
n->next = new Node();
n = n->next;
create(n);
}
//Function to insert a item in list
void insert(Node* head) {
Node* n = new Node();
cout << "Enter the data to be added in beggining";
cin >> n->data;
n->next = head;
head = n;
}
//Function to show list
void show(Node* n) {
while (n != NULL) {
cout << n->data << endl;
n = n->next;
}
}
i am in a bit of a stand still with my program on adding a newnode to a linked it, its supposed to be added at the end of the list but i tried all i could but still having got a solution, was hoping if any of you guys could help me with it
Thanks in advance tho;
this is the bit of code
#include <iostream>
using namespace std;
struct node {
int data;
node* next;
};
node* head;
void insert(int x);
void numInsert();
void numSearch();
int main()
{
head=NULL;
int x,n;
cout <<"How many number? \n";
cin >>n;
for (int i=0; i<n; i++){
cout <<"Enter Number \n";
cin >> x;
}
node* newNode;
newNode = new node();
newNode->data=x;
newNode->next=head;
head=newNode;
/*
NewNode->next=NULL;
if (head !=NULL){
NewNode->next=head;
}
else{
head=NewNode;
}*/
int num;
cout<<"what number do you want to insert in the list \n";
cin>>num;
node *nNode;
nNode = new node();
nNode->data=num;
nNode->next=NULL;
node *prevNode;
node *currNode;
prevNode=NULL;
currNode=NULL;
{
node* nNode= new node;
nNode->data= num;
nNode->next= NULL;
currNode=NULL; prevNode=NULL;
for(currNode=head; currNode != NULL; currNode= currNode->next)
{
if (newNode->data <= currNode->data)
{
break;
}
prevNode = currNode;
}
newNode->next=prevNode->next;
prevNode->next=newNode;
}
return 0;
}
anytime i run it , gets to a point and just stops working , pls help me out, the assignment is due today and i have no clue on how to solve it properly
#include <iostream>
using namespace std;
struct node {
int data;
node* next;
};
node* head;
node* tail;
void insert(int x);
void numInsert();
void numSearch();
int main()
{
head=NULL;
tail = NULL;
int x,n;
cout <<"How many number? \n";
cin >>n;
for (int i=0; i<n; i++){
cout <<"Enter Number \n";
cin >> x;
if(head==NULL){
head = new node();
head->data = x;
head->next = NULL;
tail = head;
}else{
node* newNode;
newNode = new node();
newNode->data=x;
newNode->next = NULL;
tail->next = newNode;
tail = tail->next;
}
}
cout << "Linked List :" << "\n";
node* trav = head;
for (int i=0; i<n; i++){
cout << (trav->data) << '\n';
trav = trav->next;
}
int num;
cout<<"what number do you want to insert in the list \n";
cin>>num;
if(head==NULL){
head = new node();
head->data = num;
head->next = NULL;
tail = head;
}else{
node* newNode;
newNode = new node();
newNode->data=num;
newNode->next = NULL;
tail->next = newNode;
tail = tail->next;
}
cout << "Linked List :" << "\n";
trav = head;
while(trav != NULL){
cout << (trav->data) << '\n';
trav = trav->next;
}
return 0;
}
I got a problem with my doubly linked list. How can i make the input unique ( i don`t want it to be repeated )
for example i can input 1 and then again 1 i will have a list of 1 and 1. I need to forbid this somehow :) so the list can contain only not repeating numbers.
#include <cstdlib>
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
node* prev;
};
class Node
{
public:
Node();
~Node();
void setKopa();
void printForward();
private:
node* head;
node* tail;
node* n;
};
Node::Node()
{
setKopa();
}
Node::~Node()
{
delete n;
}
void Node::setKopa()
{
int lenght;
do
{
cout << "Input list lenght (how many elements): ";
cin >> lenght;
if(lenght<2)
cout << "Error list has to have atleast 2 elements!" <<endl;
}
while(lenght<2);
int fill;
cout << "Input "<< lenght <<" elements: "<<endl;
for (int i=0; i<lenght; i++)
{
cin>>fill;
n = new node;
n->data = fill;
if (i==0)
{
n->prev = NULL;
head = n;
tail = n;
}
else if (i+1==lenght)
{
n->prev = tail;
tail->next = n;
tail = n;
tail->next = NULL;
}
else
{
n->prev = tail;
tail->next = n;
tail = n;
}
}
}
void Node::printForward()
{
node* temp = head;
while(temp != NULL)
{
cout << temp->data << " ";
temp = temp-> next;
}
cout << endl;
}
int main()
{
Node a;
a.printForward();
system("pause");
return 0;
}
When you read input, go through the list to see if the input is already there.
With that (simple) answer out of the way, I would like to address some other things regarding your code. The first is that you have a memory leak in that you never delete the list. The second is that you don't need the class member variable n, it might as well be a local variable inside the setKopa loop.
Your way of adding new nodes is also, well, weird. It should, in my opinion, be more general instead of using the loop counter to check what to do. What I suggest is that you make a member function to add new nodes, taking the integer data as argument. This way you can call this function to add nodes anywhere, and not just in the setKopa function. In fact, I think the list should not handle that input at all, instead it should be a free-standing function called from main and which calls the addNode function.
Also the node structure doesn't need to be in the global namespace, it could be a private structure in the Node class. And speaking of the Node class, shouldn't it really be called List instead?
So if I may suggest, you might want to do something like this:
#include <iostream>
class List
{
public:
List()
: head(nullptr), tail(nullptr)
{}
~List();
void addNode(const int data);
void printAll() const;
private:
struct node
{
node()
: next(nullptr), prev(nullptr)
{}
node* next;
node* prev;
int data;
};
node* head;
node* tail;
};
List::~List()
{
for (node* next, *cur = head; cur; cur = next)
{
next = cur->next;
delete cur;
}
}
void List::addNode(const int data)
{
node* n = new node;
n->data = data;
if (tail == nullptr)
{
// First node in list
head = tail = n;
}
else
{
n->prev = tail;
tail->next = n;
tail = n;
}
}
void List::printAll() const
{
std::cout << "{ ";
for (node* cur = head; cur != nullptr; cur = cur->next)
std::cout << cur->data << ' ';
std::cout << "}\n";
}
int main()
{
List list;
for (int i = 0; i < 10; ++i)
list.addNode(i);
list.printAll();
}
The above code should print
{ 0 1 2 3 4 5 6 7 8 9 }
Replace the node-adding loop with your own.