linked list union - c++

In my "void union" function I am unsure how to insert the data from both linked lists "A" and "B" that the user has input respectively since the "AUB" is not within the void function. I would have put:
AUB.insert
but I was unsure. Any suggestions?
#include "stdafx.h"
#include <iostream>
using namespace std;
class Sets
{
private:struct NODE
{
int info;
NODE *next;
};
NODE *list;
public:Sets()
{
list=NULL;
}
void Insert(int x)
{
NODE *p=list, *q=list, *r;
//create a new node
r = new (NODE);
r->info = x;
r->next = NULL;
//find the insertion place
while(p != NULL && p->info < x)
{
q=p;
p=p->next;
}
if(p==list)//x is the first info
{
list=r;
r->next=p;
}
else if(p==NULL)//x is the last info
{
q->next=r;
}
else //x is neither forst nor last info
{
r->next=p;
q->next=r;
}
}
void display()
{
NODE *p=list;
while(p != NULL)
{
cout << p->info << "-->";
p=p->next;
}
cout << "NULL\n";
}
void Union(Sets setA,Sets setB)
{
NODE *p=setA.list, *q=setB.list;
while(p != NULL && q != NULL)
{
if(p->info > q-> info)
{
(q->info)
q=q->next;
}
else if(p->info == q->info)
{
insert(p->info)
p=p->next;
q=q->next;
}
else//P->info < q->info
{
insert(p->info);
p=p->next;
}
}
while(p !=NULL)
{
insert(p->info);
p=p->next;
}
while(q != NULL)
{
insert(q->info);
q=q->next;
}
}
};
int main()
{
//create a set of integers
int x;
Sets A, B, setAUB;
cout << "Enter data for setA:\n";
cout << "Enter a group of positive integer numbers with -1 at the end end: ";
cin >> x;
while(x != -1)
{
A.Insert(x);
cin >> x;
};
//display setA
cout << endl << "setA=";
A.display();
cout << "Enter data for setB:\n";
cout << "Enter a group of positive integer numbers with -1 at the end end: ";
cin >> x;
while(x != -1)
{
B.Insert(x);
cin >> x;
};
//display setB
cout << endl << "setB=";
B.display();
setAUB.Union(A, B);
//display setAUB
cout << endl << "setAUB=";
setAUB.display();
system ("pause");
//terminate program
return 0;
};

You define it: void Union(Sets setA,Sets setB).
What are you doing? Both passed by value, and the return value is void - where does the result go?
Does your current object (this in the Union function) become that union? If so, what happens to the data already in it? You're not deleting it, so you're basically merging three sets, not two...
I would suggest to create a static merge function that would take the two parameters and return a new list which would be the merge of the two.
Otherwise, create a regular merge function, that would only take 1 parameter, and merge it into the current object.
By the way - why Sets, when it is obviously a sorted linked list?

Related

While traversing the link list to read data my function prints up to penultimate node only, Suggest a way to print the whole list

I made a linked list in C++. For in which I have a function named: ListTraverse(). Which accepts a Node type pointer variable, where Node is my class. Please suggest me a method where it prints up to the last node.
Here is function call:
ListTraverse(&head);
And here is the function definition:
void ListTraverse(Node* node)
{
//Prints upto penultimate node
while (node->next != NULL)
{
cout << "\nNode details:\t"
<< node->read_data();
node=node->next;
}
}
And here you have the entire code.
#include <bits/stdc++.h>
#include <stdlib.h>
#include<typeinfo>
using namespace std;
class Node
{
private:
int data;
public:
Node *next;
void push_data(int x)
{
data = x;
}
int read_data()
{
return data;
}
};
void ListTraverse(Node *);
int main()
{
system("CLS");
//Creating Node type variables
Node head, second, tail;
int num, choice;
//Getting user input
cout << "Enter a number for head:\t";
cin >> num;
head.push_data(num);
cout << "Enter a number for second:\t";
cin >> num;
second.push_data(num);
cout << "Enter a number for tail:\t";
cin >> num;
tail.push_data(num);
//Assigning pointers to link up
head.next = &second;
second.next = &tail;
tail.next = NULL;
cout << "If you want to read data press 1:\t";
cin >> choice;
switch (choice)
{
case 1:
ListTraverse(&head);
break;
default:
cout << "Invalid choice";
break;
}
return 0;
}
//Funtion to print Data
void ListTraverse(Node* node)
{
//Prints upto penultimate node
while (node->next != NULL)
{
cout << "\nNode details:\t"
<< node->read_data();
node=node->next;
}
}
You should re-phrase your question. It seems that
my function prints up to penultimate node only
is the problem.
you wanted to print the whole list, not penultimate. And the fix is
void ListTraverse(Node* node)
{
//Prints upto the last node
while (node)
{
cout << "\nNode details:\t"
<< node->read_data();
node=node->next;
}
}

Better way to code linked list?

I wrote this Linked List code and I am not able to create a single linked list since the value pointed by memory location of nodeValue in main function keep changing which in turn changes the head and tail value. I solved this by creating a Node object array((like nodeValue[5]) and passing the value, but this limits to 5 values. Is there a way to efficient way to code this without using a array of objects?
#include<iostream>
#include<string>
using namespace std;
class Node
{
public:
int value;
Node *nextNodePointer;
};
class linkedList
{
private:
int count = 0;
public:
Node *Head;
Node *Tail;
void AddNodeAfter(Node *);
//void removeNodeAfter(Node *);
void displayValues();
};
void linkedList::AddNodeAfter(Node *temp)
{
if (this->count == 0)
{
Head = temp;
Tail = temp;
count++;
}
else
{
Tail->nextNodePointer = temp;
Tail = temp;
count++;
}
}
Node createNodeObjects()
{
cout<< endl << "Enter integer value :";
Node temp;
cin >> temp.value;
temp.nextNodePointer = NULL;
return temp;
}
void linkedList::displayValues()
{
if (count == 0)
{
cout << endl << "Nothing to display";
}
else
{
Node value;
value = *Head;
for (int i = 1; i <= count; i++)
{
cout << endl << "Value: " << value.value;
value = *value.nextNodePointer;
}
}
}
int main()
{
cout << "Creating basic linked list" << endl;
linkedList LinkedList;
Node nodeValue;
while (1)
{
cout << endl << "Do you want to add a value to Node ?<Y/N> : ";
char choice;
cin >> choice;
if (choice == 'Y')
{
nodeValue = createNodeObjects();
LinkedList.AddNodeAfter(&nodeValue);
}
else
if (choice == 'N')
{
LinkedList.displayValues();
break;
}
else
cout << "Wrong choice" << endl;
}
}
In C++ , you can use list library ...
http://www.cplusplus.com/reference/list/list/

How to create a doubly linked list of integers in ascending sorted order?

I'm having hard time to finish the code to get the following steps:
how to read in a file of positive integers (>0)?
how to create a doubly linked list of integers in ascending sorted order?
how to write a method to print the entire list in ascending or descending order (input parameter ā€˜Aā€™ or ā€˜Dā€™ tells direction to print)?
how notify the user with a message if the number to add is already in the list or if the number is not in the list if they to delete a number not in the list.
There's no error when i run the program, just trying to solve the 4 steps above.
Here's what I have done so far
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct node
{
int number;
node *next;
};
bool isEmpty(node *head);
char menu();
void insertAsFirstElement(node *&head, node *&last, int number);
void inser(node*&head, node*&last, int number);
void remove(node *&head, node *&last);
void showlist(node *current);
int numIntElement(ifstream&x);
int main() {
string filename;
cout << " Please enter the name of the file = ";
cin >> filename;
ifstream myfile;
myfile.open(filename);
if (!myfile.is_open()) {
cout << endl << " failed to open file, check that it exists and you have access \n" << "\n" << endl;
}
else if (myfile.is_open())
{
ifstream x;
numIntElement(x);
cout << " File exists \n";
////
node * head = NULL;
node *last = NULL;
char choice;
int number;
do {
choice = menu();
switch (choice)
{
case '1':
cout << " Please enter number : ";
cin >> number;
inser(head, last, number);
break;
case '2':
remove(head, last);
case '3':
showlist(head);
break;
default:
break;
}
} while (choice != '4');
{
}
}
system("pause");
return 0;
}
int numIntElement(ifstream&x) {
int n = 0;
int m;
ifstream myfile("file.txt");
int countsingfie = 0;
while (!myfile.eof())
{
myfile >> n;
countsingfie += n;
if (countsingfie == 0) {
cout << "Error : file exist but no data " << endl;
}
cout << "total number " << countsingfie << "\n" << endl;
return countsingfie;
}
}
bool isEmpty(node *head) {
if (head == NULL) {
return true;
}
else
{
return false;
}
}
char menu() {
char choice;
cout << " Main Menu \n";
cout << " 1 . Add a number \n";
cout << " 2 . Delete a number from the list \n";
cout << " 3 . Show the list \n";
cout << " 4. Exit \n";
cin >> choice;
return choice;
}
void insertAsFirstElement(node *&head, node *&last, int number) {
node *temp = new node;
temp->number = number;
temp->next = NULL;
head = temp;
last = temp;
}
void inser(node*&head, node*&last, int number) {
if (isEmpty(head)>0){
insertAsFirstElement(head, last, number);
}
else if (isEmpty(head) < 0)
{
cout << " Please enter a number above 0 " << endl;
}
else
{
node *temp = new node;
temp->number = number;
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void remove(node *&head, node *&last) {
if (isEmpty(head)) {
cout << " Sorry, The list is already empty \n";
}
else if (head == last)
{
delete head;
head = NULL;
last = NULL;
}
else
{
node *temp = head;
head = head->next;
delete temp;
}
}
void showlist(node *current) {
if (isEmpty(current)) {
cout << " The list is empty \n";
}
else
{
cout << " The list contains: \n ";
while (current != NULL)
{
cout << current->number << endl;
current = current->next;
}
}
}

Why is this function causing a crash? (Multilist)

I'm working on my first multilist and it has been nothing but a nightmare so far. Right now, I am allowing the user to place the x,y spots (class_number,student_number) in on their own. My node looks like this:
typedef struct node {
int student_number;
int class_number;
struct node* classpointer;
struct node* studentpointer;
}* nodePtr;
Initialized with
List::List() {
head = nullptr;
currClass = nullptr;
currStudent = nullptr;
}
To add in the data values and set up pointers I have two functions.
void List::addNodeToClass() {
nodePtr n = new node;
n->classpointer = NULL;
cout << "What class number would you like to add?" << endl;
int x;
cin >> x;
n->class_number = x;
if(head != NULL) {
currClass = head;
while (currClass->classpointer != NULL) {
currClass = currClass->classpointer;
}
currClass->classpointer = n;
}
else {
head = n;
}
}
And
void List::addNodeToStudent() {
nodePtr n = new node;
n->studentpointer = NULL;
cout << "What student number would you like to add?" << endl;
int x;
cin >> x;
n->student_number = x;
if(head != NULL) {
currStudent = head;
while (currStudent->studentpointer != NULL) {
currStudent = currStudent->studentpointer;
}
currStudent->studentpointer = n;
}
else {
head = n;
}
}
I make function calls to both of these functions in my menu() function, and in main() I only call for menu()
int menu() {
int input;
List List;
while (input != 3) {
cout << " " << endl;
cout << "Press '1' to input a node" << endl;
cout << "Press '2' to view the list of nodes" << endl;
cout << "Press '3' to exit" << endl;
cout << " " << endl;
cin >> input;
if (input == 1) {
List.addNodeToClass();
List.addNodeToStudent();
}
else if (input == 2) {
List.PrintList();
}
else if (input == 3) {
return 0;
}
else {
cout <<"That is an invalid key" << endl;
}
}
}
When I run the program I am able to input the class node, then when I go to enter the student node, after hitting enter the program crashes. I know that there is a lot to look through, but I can't understand why it is. If someone would be able to tell me what I am doing wrong here I would greatly appreciate it. Thank you.
The addNodeToClass function never sets node->studentpointer. So when you follow that pointer in addNodeToStudent, you are dereferencing garbage.
Your code would be safer with a default node constructor:
typedef struct node {
node()
{
student_number = 0;
class_number = 0;
classpointer = nullptr;
studentpointer = nullptr;
}
int student_number;
int class_number;
struct node* classpointer;
struct node* studentpointer;
}* nodePtr;
And this would fix your issue because those attributes are not always initialized in your code (new node does not initialize the node attributes if there is no such constructor).

Recursive Ascending and Recursive Descending Order Functions for a Linked List

This is a homework assignment, I've written most of the code already, the only thing I can't figure out is that I have to have a recursive function to sort the linked list in ascending order, and a recursive function to sort the linked list in descending order. I'm pretty lost.
Here is my entire code.
using namespace std;
struct ListNode;
typedef ListNode* ListPtr;
struct ListNode
{
int number;
ListPtr next;
ListNode(int value, ListPtr ptr = NULL)
{
number = value;
next = ptr;
}
};
char Menu();
void Add(ListPtr &, int);
void Delete(ListPtr &, int);
void Ascend(ListPtr &);
void Descend(ListPtr &);
void Print(ListPtr &);
void DeleteList(ListPtr &);
int main()
{
ListPtr head = NULL;
char answer;
int input;
answer = Menu();
while(answer != 'Q')
{
if(answer == 'A')
{
cout << "Please enter in an integer: ";
cin >> input;
Add(head, input);
}
else if(answer == 'D')
{
cin >> input;
Delete(head, input);
}
else if(answer == 'P')
{
Ascend(head);
}
else if(answer == 'O')
{
Descend(head);
}
else if(answer == 'N')
{
Print(head);
}
else
{
cout << "Incorrect input, please try again.\n";
}
answer = Menu();
}
DeleteList(head);
return 0;
}
char Menu()
{
char uinput;
cout << "Please enter in one of the following:\n";
cout << "A: Add an item to the end of the list.\n";
cout << "D: Delete an item from the list.\n";
cout << "P: Print the list in ascending order.\n";
cout << "O: Print the list in descending order.\n";
cout << "N: Display the number of items in the list.\n";
cout << "Q: Quit.\n";
return toupper(uinput);
}
void Add(ListPtr &start, int item)
{
if(start->number > item || start == NULL)
start = new ListNode(item, start);
else
Add(start->next, item);
}
void Delete(ListPtr &start, int item)
{
if(start != NULL)
{
if(start->number == item)
ListPtr cur = start;
start = start->next;
delete cur;
}
else
{
Delete(start->next, item);
}
}
void Ascend(ListPtr &start)
{
}
void Descend(ListPtr &start)
{
}
void Print(ListPtr &start)
{
ListPtr cur = start;
int count = 0;
if(cur == NULL)
{
cout << "The list is empty.\n";
}
else
{
if(cur != NULL)
{
if(count % 10 == 0)
cout << endl;
cout << setw(5) << cur->number;
cur = cur->next;
count++;
}
}
cout << endl;
}
void DeleteList(ListPtr &start)
{
if(start != NULL)
{
DeleteList(start->next);
cout << "Deleting item " << start->number << endl;
delete start;
}
}
For the recursion part, one method is to recursively divide the lists into two lists, left and right, until the list size is reduced to 1 (or zero) in which case the recursive function just returns the list, else it's followed by code in the recursive function that merges the returned left and right lists, and returns the merged list.
Have you learned how to split a linked list into two lists? Normally this is done using two pointers. I'm not sure what you've been taught and what you're supposed to figure out. What level of programming class is this?