Linked List Priority Queue with addition conditions - c++

I have tired coding the normal priority. Now i would want to add in 1 or 2 more conditions into my code.
Here's my current normal priority code:
void queue::addToQueueList(int newPriority, double newFare, int custID)
{
node* newnode= new node;
newnode->priority= newPriority;
newnode->fare = newFare;
newnode->cusID = custID;
newnode->next= NULL;
if (front == NULL || newnode->priority < front->priority)
{
newnode->next = front;
front = newnode;
}
else
{
node* q = front;
node* p;
while (q->next != NULL && q->next->priority <= newnode->priority)
{
q=q->next;
}
newnode->next = q->next;
q->next = newnode;
}
}
how can i add in addition condition example if found priority same, compare the fare. the highest of the fare will be priority.
Thanks

If I have correctly understood you need the following
#include <utility>
//...
void queue::addToQueueList(int newPriority, double newFare, int custID)
{
node* newnode= new node;
newnode->priority= newPriority;
newnode->fare = newFare;
newnode->cusID = custID;
newnode->next= NULL;
auto p = std::make_pair( newPriority, newFare );
if (front == NULL || p < std::make_pair( front->priority, front->fare ) )
{
newnode->next = front;
front = newnode;
}
else
{
node* q = front;
while (q->next != NULL &&
std::make_pair( q->next->priority, q->next->fare ) <= p)
{
q=q->next;
}
newnode->next = q->next;
q->next = newnode;
}
}
Also it seems that statement
node* p;
may be removed from the function.

This is what i did:
void queue::addToQueueList(int newPriority, double newFare, int custID)
{
node* newnode= new node;
newnode->priority= newPriority;
newnode->fare = newFare;
newnode->cusID = custID;
newnode->next= NULL;
if (front == NULL || newnode->priority < front->priority)
{
newnode->next = front;
front = newnode;
}
else
{
node* q = front;
node* p;
while (q->next != NULL && q->next->priority <= newnode->priority)
{
p=q;
q=q->next;
}
bool chk = compare(q,newnode);
if(chk)
{
p->next = newnode;
newnode->next = q;
}
else
{
newnode->next = q->next;
q->next = newnode;
}
}
}
bool queue::compare(node* const& n1, node* const& n2)
{
bool check = false;
if(n1->priority == n2->priority)
{
if(n2->fare > n1->fare)
{
check = true;
}
}
return check;
}

Related

How to use subscript operator overloading in linklist using c++

I want to use subscript operator overloading in linklist but everytime it give me Segmentation fault (core dumped) ERROR! MY TASK IS : (Overload [] operator. Use for loop in main to display it.) I ALSO PROVIDING THE TASK LINK BELOW
//task link
[LINK OF TASK] https://anonymfile.com/r1XKK/dsa-a3.pdf
//MY CODE IS :
#include <iostream>
using namespace std;
class LinkedList
{
private:
class Node
{
public:
int data;
Node * next;
Node(int data)
{
this->data = data;
this->next = NULL;
}
};
public:
Node *head;
LinkedList(){
head = NULL;
}
//Write a copy constructor. Also copy must be deep.
LinkedList(LinkedList& S)
{
head = S.head;
}
//Overload [] operator. Use for loop in main to display it.
void operator[](int i) {
head->data = i;
}
void InsertAtEnd(int data){
if (head == NULL)
{
head = new Node(data);
return;
}
Node * temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new Node(data);
}
void Insert(int d1, int d2)//Add the node of data d2 after the node with data d1. If d2 is not available add it to the end.
{
if (head == NULL)
{
Node * n = new Node(d2);
n->next = head;
head = n;
return;
}
Node * temp = head;
while (temp != NULL)
{
if (temp->data == d1)
{
Node * temp1 = temp->next;
temp->next = new Node(d2);
temp->next->next = temp1;
}
temp = temp->next;
}
}
void Delete(int data){
Node * todelete;
if(head->data == data){
todelete = head;
head = head->next;
free(todelete);
return;
}
Node *temp = head;
while(temp->next != NULL){
if(temp->next->data == data){
todelete = temp->next;
temp->next = temp->next->next;
free(todelete);
break;
}
temp = temp->next;
}
} // Deletes a node with data.
int getSize(){
Node * temp = head;
int size = 0;
while(temp != NULL){
temp = temp->next;
size++;
}
return size;
} //returns the count of elements in the list
bool IsEmpty(){
if(head == NULL){
return true;
}
else{
return false;
}
} //Returns true if empty.
void Merge(Node * list){
//merge
Node * temp = head;
while(temp != NULL){
if(temp->next == NULL and list != NULL){
temp->next = list;
break;
}
temp = temp->next;
}
//DISPLAY
while(head!=NULL){
cout<<head->data<<"->";
head=head->next;
}
cout<<"NULL"<<endl;
} //Merges the to the calling class.
void Erase(){
Node * erase;
while(head!= NULL){
erase = head;
head = head->next;
head = NULL;
}
free(erase);
} //Deletes every node in an array.
void SelectiveErase(int num) //Find num and delete everything after num.
{
Node * temp = head;
Node * todelete;
while(temp != NULL){
if(temp->data == num){
Node * erase = temp->next;
while(temp->next != NULL){
erase = temp->next;
temp->next = temp->next->next;
temp->next = NULL;
}
free(erase);
break;
}
temp = temp->next;
}
}
int FindNCount(int find)//Find and return count of all occurrence.
{
int counter = 0;
bool flag = false;
Node * temp = head;
while(temp->data!= find){
temp = temp->next;
counter++;
}
return counter;
}
int RemoveDuplicate(int find)//Find and remove every duplicate element in the list. Make //elements unique.
{
Node * temp = head;
Node *temp1;
while(temp != NULL){
temp1 = temp;
while(temp1->next != NULL){
if(temp->data == temp1->next->data and temp->data == find and temp1->next->data == find){
Node *todelete = temp1->next;
temp1->next = temp1->next->next;
free(todelete);
}
else{
temp1 = temp1->next;
}
}
temp = temp->next;
}
return find;
}
void FindNReplace(int find, int data)//Find and replace all occurrence recursively.
{
Node * temp = head;
while(temp != NULL){
if(temp->data == find){
temp->data = data;
break;
}
temp = temp->next;
}
}
void Display(){
static Node * temp= head;
if(temp == NULL){ cout << "NULL" << endl; return;}
cout << temp->data<<"->";
temp = temp->next;
Display();
}
};
void Swap() // swap the contents of one list with another list of same type and size. Also write parameter
{
LinkedList L,L1;
cout<<"AFTER SWAPING THE VALUE OF FIRST LIST \n";
while(L.head != NULL && L1.head != NULL){
int temp = L.head->data;
L.head->data = L1.head->data;
L1.head->data = temp;
cout<<L.head->data<<"\n";
L.head = L.head->next;
L1.head = L1.head->next;
}
cout<<endl;
}
int main()
{
// You must call Display function after every function.
LinkedList L{};
L[23];
// LinkedList L1;
// L1.InsertAtEnd(5);
// L1.InsertAtEnd(6);
//L.Erase();
// cout<<L.FindNCount(1)<<endl;
//L.SelectiveErase(2);
//L.Display();
//L.Merge(L1.head);
//L.RemoveDuplicate(2);
//L.Display();
//Swap();
return 0;
}
Overloading the subscript operator should return something. The assignment looks a bit vague, but I hope this will fix it:
//Overload [] operator. Use for loop in main to display it.
Node* operator[](int i) {
Node* nodePtr = head;
int counter = 0;
while (nodePtr != NULL && counter != i) {
nodePtr = nodePtr->next;
counter++;
}
return nodePtr;
}

Merge sort with doubly linked lists (using the tail-head representation)

I want to implement a merge-sorting algorithm, that is good for a doubly linked list with two "watches".
The watches are: head and tail, where head->prev is equal to NULL, head->next is equal to the first item, tail->prev is equal to the last item and tail->next is equal to NULL
Here is a graphic representation on how a doubly linked list would look like:
I have implemented the merge sort algorithm as such:
//Function to merge two halves of list.
struct Node *merge(struct Node *first, struct Node *second)
{
//base cases when either of two halves is null.
if (!first)
return second;
if (!second)
return first;
//comparing data in both halves and storing the smaller in result and
//recursively calling the merge function for next node in result.
if (first->data < second->data)
{
first->next = merge(first->next,second);
first->next->prev = first;
first->prev = NULL;
//returning the resultant list.
return first;
}
else
{
second->next = merge(first,second->next);
second->next->prev = second;
second->prev = NULL;
//returning the resultant list.
return second;
}
}
//Function to split the list into two halves.
struct Node *splitList(struct Node *head)
{
//using two pointers to find the midpoint of list
struct Node *fast = head,*slow = head;
//first pointer, slow moves 1 node and second pointer, fast moves
//2 nodes in one iteration.
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
//slow is before the midpoint in the list, so we split the
//list in two halves from that point.
struct Node *temp = slow->next;
slow->next = NULL;
return temp;
}
//Function to sort the given doubly linked list using Merge Sort.
struct Node *sortDoubly(struct Node *head)
{
if (!head || !head->next)
return head;
//splitting the list into two halves.
struct Node *second = splitList(head);
//calling the sortDoubly function recursively for both parts separately.
head = sortDoubly(head);
second = sortDoubly(second);
//calling the function to merge both halves.
return merge(head, second);
}
source: geeksforgeeks
However, upon running the code, when I try to write the sorted doubly linked list, I get an error, when the deconstructor tries deleting the last item, as the algorithm is not working with a head-tail type doubly linked list.
What is a fix I could try?
The full code here:
#include <fstream>
#include <iostream>
using namespace std;
class node {
public:
int value;
node* prev;
node* next;
};
class DLLista {
private:
node* head;
node* tail;
public:
DLLista();
~DLLista();
node* createNode(int value);
void freeNode(node* p);
void insertBefore(node* p, int value);
void insertAfter(node* p, int value);
void deleteBefore(node* p);
void deleteAfter(node* p);
void deleteNode(node* p);
void push_back(node* p);
void push_front(node* p);
void printFront();
void printBack();
node* firstItem();
node* lastItem();
};
DLLista::DLLista() {
head = new node;
tail = new node;
head->prev = NULL;
head->next = tail;
tail->prev = head;
tail->next = NULL;
}
DLLista::~DLLista() {
while (head->next != tail) {
deleteNode(lastItem());
}
delete head;
delete tail;
}
node* DLLista::createNode(int value) {
node* newnode = new node;
newnode->value = value;
newnode->prev = newnode->next = NULL;
return newnode;
}
void DLLista::freeNode(node* p) {
delete p;
}
void DLLista::insertBefore(node* p, int value) {
node* newnode = createNode(value);
p->prev->next = newnode;
newnode->prev = p->prev;
newnode->next = p;
p->prev = newnode;
}
void DLLista::insertAfter(node* p, int value) {
node* newnode = createNode(value);
newnode->next = p->next;
newnode->prev = p;
p->next->prev = newnode;
p->next = newnode;
}
void DLLista::deleteBefore(node* p) {
node* del = p->prev;
if (del != NULL) {
del->prev->next = p;
p->prev = del->prev;
freeNode(del);
}
else {
cout << "Error:deleteBefore";
}
}
void DLLista::deleteAfter(node* p) {
node* del = p->next;
if (del != NULL) {
p->next = del->next;
del->next->prev = p;
freeNode(del);
}
else {
cout << "Error:deleteAfter";
}
}
void DLLista::deleteNode(node* p) {
if (p != head && p != tail) {
p->prev->next = p->next;
p->next->prev = p->prev;
freeNode(p);
}
else {
cout << "Error:deleteNode";
}
}
void DLLista::push_back(node* p) {
tail->prev->next = p;
p->prev = tail->prev;
p->next = tail;
tail->prev = p;
}
void DLLista::push_front(node* p) {
head->next->prev = p;
p->next = head->next;
p->prev = head;
head->next = p;
}
void DLLista::printFront() {
node* p = head->next;
while (p != tail) {
cout << p->value << " ";
p = p->next;
}
}
void DLLista::printBack() {
node* p = tail->prev;
while (p != head) {
cout << p->value << " ";
p = p->prev;
}
}
node* DLLista::firstItem() {
return head->next;
}
node* DLLista::lastItem() {
return tail->prev;
}
//Implementation of merge sort algorithm
void input(const char* file, DLLista& list) {
ifstream fin(file);
int n;
fin >> n;
int tmp;
for (int i = 0; i < n; i++) {
fin >> tmp;
node* newnode = list.createNode(tmp);
list.push_back(newnode);
}
}
node* merge(node* first, node* second) {
if (first == NULL) {
return second;
}
if (second == NULL) {
return first;
}
if (first->value < second->value) {
first->next = merge(first->next, second);
first->next->prev = first;
first->prev = NULL;
return first;
}
else {
second->next = merge(first, second->next);
second->next->prev = second;
second->prev = NULL;
return second;
}
}
node* split(node* head) {
node* fast = head;
node* slow = head;
while (fast->next && fast->next->next) {
fast = fast->next->next;
slow = slow->next;
}
node* tmp = slow->next;
slow->next = NULL;
return tmp;
}
node* sort(node* head) {
if (head == NULL || head->next == NULL) {
return head;
}
node* second = split(head);
head = sort(head);
second = sort(second);
return merge(head, second);
}
int main() {
DLLista list;
input("input1.txt ", list);
list.printFront();
node* head = list.firstItem()->prev;
sort(head);
}
input1.txt:
6
1 2 6 5 4 3
expected output:
1 2 3 4 5 6

Segmentation fault on insertion of more than one elements in the linked list in a sorted order

I tried to do an insertion sort in a linked list. When only one element is inserted(i.e the first one),it executes well and fine but for multiple elements it gives segmentation fault. Can anyone tell me where the problem is?
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
} *head = NULL;
node* createNode(int x)
{
node *temp = new node;
temp->data = x;
temp->next = NULL;
return temp;
}
void insertSort(int x)
{
if(head==NULL)
{
node *temp = createNode(x);
head = temp;
return;
}
node *temp = createNode(x);
node *prev = NULL;
node *curr = head;
bool inserted = false;
while(curr != NULL || !inserted)
{
if(temp->data < head->data)
{
temp->next = head;
head = temp;
inserted = true;
}
else
{
if(temp->data < curr->data)
{
prev->next = temp;
temp->next = curr;
inserted = true;
}
else
{
prev = curr;
curr = curr->next;
}
}
}
if(!inserted)
{
prev->next = temp;
}
}
void display()
{
node *p = head;
while(p != NULL)
{
cout<<p->data<<" ";
p = p->next;
}
}
For starters the function insertSort has redundant code
if(head==NULL)
{
node *temp = createNode(x);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
head = temp;
return;
}
node *temp = createNode(x);
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Secondly the condition in the while statement
while(curr != NULL || !inserted)
is incorrect. There must be
while(curr != NULL && !inserted)
In any case the function is too complicated. It can be written simpler.
Here is a demonstrative program that shows how the function can be implemented.
#include <iostream>
#include <cstdlib>
#include <ctime>
struct node
{
int data;
node* next;
} *head = nullptr;
node* createNode(int x)
{
return new node { x, nullptr };
}
std::ostream & display( std::ostream &os = std::cout )
{
for ( node *current = head; current != nullptr; current = current->next )
{
os << current->data << " - > ";
}
return os << "NULL";
}
void insertSort( int x )
{
node *new_node = createNode( x );
node **current = &head;
while ( *current != NULL && not ( x < ( *current )->data ) )
{
current = &( *current )->next;
}
new_node->next = *current;
*current = new_node;
}
int main()
{
const int N = 10;
std::srand( ( unsigned int )std::time( nullptr ) );
for ( int i = 0; i < N; i++ ) insertSort( std::rand() % N );
display() << '\n';
return 0;
}
The program output might look like
1 - > 2 - > 2 - > 3 - > 3 - > 3 - > 3 - > 8 - > 9 - > 9 - > NULL

doublyLinkedList compiles but crashes when executed

My doublyLinkedList works until I call the removeAt(int i) function but I don't know what is wrong with it.
Here is my doublyLinkedList:
class node
{
public:
node * prev;
node * next;
double data;
};
class doublyLinkedList
{
private:
node * head;
node * tail;
node * findAt(int i)
{
node * current = head;
for (int j = 1; j <= i; j++)
{
current = current->next;
}
return current;
}
void removeNode(node * doomedNode)
{
if (head == tail && doomedNode == head)
{
head = NULL;
tail = NULL;
delete doomedNode;
}
else if (doomedNode == tail && tail != head)
{
tail = tail->prev;
tail->next = NULL;
delete doomedNode;
}
else if (doomedNode == head && head != tail)
{
head = head->next;
head->prev = NULL;
delete doomedNode;
}
else
{
node * ahead = doomedNode->prev;
node * behind = doomedNode->next;
ahead->prev = behind;
behind->next = ahead;
delete doomedNode;
}
}
public:
doublyLinkedList()
{
head = NULL;
tail = NULL;
}
~doublyLinkedList()
{
node * temp;
while (head != NULL)
{
temp = head->next;
delete head;
head = temp;
}
}
void addBack(double x)
{
node * newItem = new node;
newItem->data = x;
if (head == NULL && tail == NULL)
{
newItem->prev = NULL;
newItem->next = NULL;
head = newItem;
tail = newItem;
}
else
{
newItem->prev = tail;
newItem->next = NULL;
tail->next = newItem;
tail = newItem;
}
}
void removeAt(int i)
{
node * current = head; node * foundNode; node * deletedNode;
int j = 1;
while (current != NULL)
{
current = current->next;
j++;
}
if (i >= j && i > 0)
{
foundNode = findAt(i);
removeNode(foundNode);
}
}
};
Can someone please tell me what's wrong?

Crash, while printing contents of linked-list

I'm having some trouble printing out the contents of a linked list. I'm using an example code that I found somewhere. I did edit it a bit, but I don't think that's why it's crashing.
class stringlist
{
struct node
{
std::string data;
node* next;
};
node* head;
node* tail;
public:
BOOLEAN append(std::string newdata)
{
if (head)
{
tail->next = new node;
if (tail->next != NULL)
{
tail=tail->next;
tail->data = newdata;
return TRUE;
}
else
return FALSE;
}
else
{
head = new node;
if (head != NULL)
{
tail = head;
head->data = newdata;
return TRUE;
}
else
return FALSE;
}
}
BOOLEAN clear(std::string deldata)
{
node* temp1 = head;
node* temp2 = NULL;
BOOLEAN result = FALSE;
while (temp1 != NULL)
{
if (temp1->data == deldata)
{
if (temp1 == head)
head=temp1->next;
if (temp1==tail)
tail = temp2;
if (temp2 != NULL)
temp2->next = temp1->next;
delete temp1;
if (temp2 == NULL)
temp1 = head;
else
temp1 = temp2->next;
result = TRUE;
}
else // temp1->data != deldata
{
temp2 = temp1;
temp1 = temp1->next;
}
}
return result;
}
BOOLEAN exists(std::string finddata)
{
node* temp = head;
BOOLEAN found = FALSE;
while (temp != NULL && !found)
{
if (temp->data == finddata)
found=true;
else
temp = temp->next;
}
return found;
}
void print()
{
node* tmp = head;
while (tmp)
{
printf("%s", tmp->data.c_str());
tmp = tmp->next;
}
}
stringlist()
{
head=NULL;
tail=NULL;
}
};
My main() function is really simple:
int main()
{
stringlist mylist;
if (mylist.append("something"))
count++;
if (mylist.append("else"))
count++;
if (mylist.append("yet"))
count++;
cout<<"Added "<<count<<" items\n";
mylist.print();
return 0;
}
For some reason in Print() tmp is never NULL
in node, add a constructor to initialize next to null
As #rmn pointed out, you're not initializing the value of node->next.
BOOLEAN append(std::string newdata)
{
if (head)
{
tail->next = new node;
if (tail->next != NULL)
{
tail=tail->next;
tail->data = newdata;
tail->next = NULL; // <- this is the part that is missing
return TRUE;
}
else
return FALSE;
}
else
{
head = new node;
if (head != NULL)
{
tail = head;
head->data = newdata;
head->next = NULL; // <- it's also missing here.
return TRUE;
}
else
return FALSE;
}
}
You could solve this by having a default constructor for node:
struct node
{
std::string data;
node* next;
node() : next(NULL) { }
};
With the default constructor you won't need to add tail->next = NULL;.
You aren't initializing head->tail appropriately in append when head==NULL initially.
Correct. That's because tail is only NULL in your code when the linked list is initially created. After you add a node, you set tail = head, and from that point in time, every time you add an element, you set tail->next = new node, and then tail = tail->next... so that tail->next always = tail.