Order Link List - c++

I have a base class called linkList and two derived class. One order link list class and unorder link list class. My order link list class is not working and i have no idea why.When i insert 3 numbers into the list it work but when i insert more than 4 values it messes up. It will also say the length of the list is larger than what it actually is. [enter image description here][1]
void insert(const T& newItem){
nodeType<T> *current;
nodeType<T> *trailCurrent=nullptr;
nodeType<T> *newNode;
bool found;
newNode = new nodeType<T>;
newNode->info = newItem;
newNode->next = nullptr;
//if the list is empty add to empty list
if (this->first == nullptr){
this->first = newNode;
this->last = newNode;
this->count++;
}
else {
current = this->first;
found = false;
while (current != nullptr && !found){
if (current->info >= newItem)
found = true;
else{
trailCurrent = current;
current = current->next;
}
//if current value is first item into the list insert into the front
if (current == this->first){
newNode->next = this->first;
this->first=newNode;
this->count++;
}
else{
trailCurrent->next = newNode;
newNode->next=current;
if (current == nullptr)
this->last = newNode;
this->count++;
}
}
}
}

Related

Deleting a key from a circular linked list

void deletenode(string key) {
if (last == NULL) {
cout << "your circular linked list is an empty one" << endl;
}
else {
node* p = last->next;
node* prev = last;
do {
if (p->title == key) {
node* temp = p;
prev->next = p->next;
delete(temp);
}
else {
p = p->next;
prev = prev->next;
}
} while (p != last->next);
}}
I was trying to delete a node with key value. For instance, if node p->title is my key then I want to delete that node. However, I implemented it with other values but the code doesn't seem to work or delete a node with key value from my circular linked list. What is the mistake in the function?
circular linked list value "cat", "dog", "rat", "horse", the key to be deleted was "dog". When I traverse throughout the linked list after the deletion it still printed everything including "dog", which means deletion didn't work.
Anytime you write a "delete from the linked list" function, you have to account for the possibility that you are deleting from the "head" or whatever pointer you are referencing with the list. The common pattern is for the function to return the new head of the list if it changed, else return the current head.
Node* deletenode(Node* head, const string& key) {
// empty list
if (head == nullptr) {
return nullptr;
}
// single item list
if (head->next == nullptr || head->next == head) {
if (head->title == key) {
delete head;
head = nullptr;
}
return head;
}
// two or more item list, possibly circular
Node* prev = head;
Node* current = head->next;
Node* first = current;
while (current && current->title != key) {
prev = current;
current = current->next;
if (current == first) {
break;
}
}
if (current == nullptr || current->title != key) {
return head; // not found
}
prev->next = current->next;
if (current == head) {
head = current->next;
}
delete current;
return head;
}
I don't see the full code so I can't make a comment I tried to implement the function, hope it helps you with the comments.
void deleteNodeWithKey(node* head, string key)
{
node *curr = head;
node *last , *temp;
//Search for last node
while (curr->next != head)
{
curr = curr->next;
}
last = curr;
//If head is the desired key, make head's next new head
//and connect last node to new head
if (head->key == key)
{
temp = head->next;
delete head;
head = temp;
last->next = head;
return;
}
temp = head->next;
//Search for node with the given key
node *prev = head;
while (temp != head)
{
if (temp->key == key)
{
prev->next = temp->next;
delete temp;
return;
}
temp = temp->next;
prev = prev->next;
}
//If function gets here, key was not found
}
I made some changes to your code
void deletenode(string key) {
if (last == NULL) {
cout << "your circular linked list is an empty one" << endl;
}
else {
node* prev = last;
// If head is to be deleted
if (last->title == key) {
while (prev->next != last)
prev = (prev)->next;
prev->next = last->next;
free(last);
last = prev->next;
return;
}
node* p = last->next;
do {
if (p->next->title == key) {
node* temp = p->next;
p->next = temp->next;
delete(temp);
}
else {
p = p->next;
prev = prev->next;
}
} while (p != last->next);
}
}

Linked List traversal skips values

I'm new to pointers and I'm a bit confused.
I have written a function which merges and sorts two sorted linked lists. However, when I print the list after calling the function it does not have all the values of the new merged list. While debugging the code and examining the variables and memory locations, it looks like it skips over the locations and just jumps to the last memory location. After the function executes I need to have the values in a new list and leaving list1 and list2 empty. This is my method in the header file:
template <class Type>
void orderedLinkedList<Type>::mergeLists(orderedLinkedList<Type> &list1, orderedLinkedList<Type> &list2)
{
nodeType<Type> *lastSmall; //pointer to the last node of the merged list.
nodeType<Type> *first1 = list1.first;
nodeType<Type> *first2 = list2.first;
if (list1.first == NULL){ //first sublist is empty
this->first = list2.first;
list2.first = NULL;
}
else if (list2.first == NULL){ // second sublist is empty
this->first = list1.first;
list1.first = NULL;
}
else{
if (first1->info < first2->info){ //Compare first nodes
this->first = first1;
first1 = first1->link;
lastSmall = this->first;
}
else{
this->first = first2;
first2 = first2->link;
lastSmall = this->first;
}
while (first1 != NULL && first2 != NULL)
{
if(first1->info < first2->info){
lastSmall->link = first1;
lastSmall = lastSmall->link;
first1 = first1->link;
}
else{
lastSmall->link = first2;
lastSmall = lastSmall->link;
first2 = first2->link;
}
} //end while
if (first1 == NULL) //first sublist exhausted first
lastSmall->link = first2;
else //second sublist exhausted first
lastSmall->link = first1;
list1.first = NULL;
list1.last = NULL;
list2.first = NULL;
list2.last = NULL;
}
}
Then in my main.cpp I have:
int main()
{
orderedLinkedList<int> list1;
orderedLinkedList<int> list2;
orderedLinkedList<int> newList;
list1.insert(2);
list1.insert(6);
list1.insert(7);
list2.insert(3);
list2.insert(5);
list2.insert(8);
newList.mergeLists(list1, list2);
newList.print();
return 0;
}
My print function just in case:
template <class Type>
void linkedListType<Type>::print() const
{
nodeType<Type> *current; //pointer to traverse the list
current = first; //set current so that it points to
//the first node
while (current != NULL) //while more data to print
{
cout << current->info << " ";
current = current->link;
}
}//end print
Could someone please tell me what I am doing wrong here? The output should be 2 3 5 6 7 8 but instead it's 2 3 7 8.
Thanks
EDIT:
Here is my insertion function. Note that this function is from the book I'm working with. It is included in the same class that I need to add the mergeLists method to. It is written specifically for ordered lists:
template<class Type>
void orderedLinkedList<Type>::insert(const Type& newItem)
{
nodeType<Type> *current;
nodeType<Type> *trailCurrent;
nodeType<Type> *newNode;
bool found;
newNode = new nodeType<Type>;
newNode->info = newItem;
newNode->link = NULL;
//case1 list is empty
if(this->first == NULL)
{
this->first = newNode;
this->last = newNode;
this->count++;
}
else //if the list is not empty
{
current = this->first;
found = false;
while(current != NULL && !found)
{
if(current->info >= newItem)
found = true;
else
{
trailCurrent = current;
current = current->link;
}
//case2 insert newNode at the head
if(current == this->first)
{
newNode->link = this->first;
this->first = newNode;
this->count++;
}
else //case 3
{
trailCurrent->link = newNode;
newNode->link = current;
if(current == NULL)
this->last = newNode;
this->count++;
}
}
}
}
The 3 cases as according to the book are:
Case 1:
The list is initially empty. The node containing the new item is the only node
and, thus, the first node in the list.
Case 2:
The new item is smaller than the smallest item in the list. The new item goes at
the beginning of the list. In this case, we need to adjust the list’s head pointer—
that is, first. Also, count is incremented by 1.
Case 3:
The item is to be inserted somewhere in the list.
Case 3a:
The new item is larger than all the items in the list. In this case, the new
item is inserted at the end of the list. Thus, the value of current is NULL
and the new item is inserted after trailCurrent. Also, count is incremented
by 1.
Case 3b:
The new item is to be inserted somewhere in the middle of the list. In this
case, the new item is inserted between trailCurrent and current.
Also, count is incremented by 1.
The bug is in your insertion method. When you call print on the lists after inserting, you will note that the last value gets overriden:
list1.insert(2); list1.print();
list1.insert(6); list1.print();
list1.insert(7); list1.print();
list2.insert(3); list2.print();
list2.insert(5); list2.print();
list2.insert(8); list2.print();
will output:
2
2 6
2 7
3
3 5
3 8
This is because every iteration trailCurrent->link = newNode; gets called, cutting of the list the first time this happens.
So for example when 7 is inserted in list1, the loop will first set trailCurrent->link to 7 when trailCurrent is 2, and then continue and set trailCurrent->link to 7 when trailCurrent is 6. But since 2 now points to 7 and not to 6, the chain is lost, and you're stuck with only 2 and 7.
Get another book
The book you are using to learn this is outdated. C style pointers and manual memory allocation should not be used in modern C++. Try to get a modern book that teaches how to use smart pointers and modern collections, and that teaches proper debugging techniques, so you can easily detect problems as the one you stumbled over now.
Thanks to everyone who has tried to help. In the end it was a simple logic error.
I inadvertently added a curly bracket to the end of my while loop in my insertion method which resulted in the loop executing code that it wasn't supposed to more than once causing strange behavior. See the corrected code below:
while(current != NULL && !found)
{ //<-- Removed this
//code
this->count++;
}
} //<-- Removed this
And now the working code is:
template<class Type>
void orderedLinkedList<Type>::insert(const Type& newItem)
{
nodeType<Type> *current;
nodeType<Type> *trailCurrent;
nodeType<Type> *newNode;
bool found;
newNode = new nodeType<Type>;
newNode->info = newItem;
newNode->link = NULL;
//case1 list is empty
if(this->first == NULL)
{
this->first = newNode;
this->last = newNode;
this->count++;
}
else //if the list is not empty
{
current = this->first;
found = false;
while(current != NULL && !found)
if(current->info >= newItem)
found = true;
else
{
trailCurrent = current;
current = current->link;
}
//case2 insert newNode at the head
if(current == this->first)
{
newNode->link = this->first;
this->first = newNode;
this->count++;
}
else //case 3 insert newNode anywher in the list
{
trailCurrent->link = newNode;
newNode->link = current;
if(current == NULL)
this->last = newNode;
this->count++;
}
}
}

Dummy head node circular linked list, deletion problems

I am currently learning about circular linked lists and I am having problems with a circular linked list template. It is derived from an ADT linked list type.
The problems I am having are with deletion of nodes, in some occasions the program will just crash when I delete them. I know I need to implement a dummy node of some sort when I create a list to prevent this happening however I do not know were in the code to do this.
I have looked at other posts regarding this however I am still lost.
If anyone could share some guidance into how to implement this I would be so
grateful.
Thank you
Insert:
template <class Type>
void unorderedCircularLinkedList<Type>::insertFirst(const Type& newItem)
{
nodeType<Type> *newNode;
nodeType<Type> header; <--- implement here?
header.link = &header; <---- dereference the header?
newNode = new nodeType<Type>; //create the new node
newNode->info = newItem; //store the new item in the node
if (first == NULL)
{
first = newNode;
last = first;
last->link = first;
}
else
{
last->link = newNode; //make last point to new node
newNode->link = first; //make new node point to first
first = newNode; //make first point to new node
}
count++; //increment count
}
Delete:
template <class Type>
void unorderedCircularLinkedList<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //pointer to traverse the list
nodeType<Type> *trailCurrent; //pointer just before current
bool found;
if (first == NULL) //Case 1; the list is empty.
cout << "Cannot delete from an empty list."
<< endl;
else
{
if (first->info == deleteItem) //Case 2
{
current = first;
count--;
if (first->link == first) //the list has only one node
{
first = NULL;
last = NULL;
}
else if (first->link == last) //the list has two nodes
{
first = first->link;
first->link = first;
last = first;
}
else
{
first = first->link;
last->link = first;
}
delete current;
}
else //search the list for the node with the given info
{
found = false;
trailCurrent = first; //set trailCurrent to point to the first node
current = first->link; //set current to point to the second node
/* set pointer to point to the last node*/
while (current != NULL && !found)
if (current->info != deleteItem)
{
trailCurrent = current;
current = current->link;
}
else
found = true;
if (found) //Case 3; if found, delete the node
{
trailCurrent->link = current->link;
if (current == last)
first = first->link;
delete current;
count--;
//delete the node from the list
}
else
cout << "The item to be deleted is not in the list." << endl;
}
}
}
your curly braces are messed up
if (first->info == deleteItem) //Case 2
{
current = first;
count--;
//missing '}' here
if (first->link == first) //the list has only one node
{
first = NULL;
last = NULL;
}
and i think there's an extra one at the end you will find out when you add the above one

c++ linked list, insert strings

This is my homework: Create a linked list class which stores a list of unique (no duplicates allowed) strings in alphabetic order.
enter image description here
and this is what I have so far, which is not working. can anyone find the problems for me? thank you very much. the error looks like this:
+ std::_String_alloc<std::_String_base_types<char,std::allocator<char> > > {_Mypair={_Myval2={_Bx={_Buf=0x0135f988 "Adam" _Ptr=0x6d616441 <Error reading characters of string.> ...} ...} } } std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >
my code:
bool LinkedList::insert(string dataInsert) {
//remember to use find funcion to check dupcated.
if (find(dataInsert) != 0)
return false;
// build new node.
Node* newNode = new Node;
newNode->data = dataInsert;
newNode->next = NULL;
//insert into empty list
if (head == NULL)
{
head = newNode;
return true;
}
//insert before first item
if (newNode->data < head->data)
{
newNode->next = head;
head = newNode;
return true;
}
//insert somewhere after first item
Node* previous = head;
while (previous->next != NULL && previous->next->data < newNode->data)
{
previous = previous->next;
newNode->next = previous->next;
previous->next = newNode;
return true;
}
}
Your below while might have some problems because newNode was inserted every time when you found the next node has smaller data than newNode.
while (previous->next != NULL && previous->next->data < newNode->data)
{
previous = previous->next;
newNode->next = previous->next;
previous->next = newNode;
return true;
}
I think your solution is finding a position of the largest node that smaller than newNode. You can refer below code:
while (previous->next != NULL && previous->next->data < newNode->data)
{
previous = previous->next;
}
newNode->next = previous->next;
previous->next = newNode;
return true;

deleting all specific keys found in linked list

I am trying to delete all specific key element in my linked list in one function .
that is if linked list has 1 2 2 3 4 4 5 5 8 2 6 32 4 6 7 7 then if I pass the function 2 that function delete all the 2's in linked list
my linked list is here
class float_list
{
struct node
{
double data;
struct node *next;
};
node *head;
public:
float_list(void)
{
head = nullptr;
};
void appendNode(double);
void print_list();
void deleteNode(double);
};
now my deleteNode(double is here)
void float_list::deleteNode(double num)
{
node *nextptr, *previousptr = nullptr;
nextptr=head;
if(!head->data){return;}
if(head->data==num)
{
nextptr= head->next;
delete head;
head = nextptr;
}
else
while(nextptr)
{
previousptr= nextptr;
if(nextptr->data==num)
{
previousptr->next = nextptr->next;
delete nextptr;
cout<<"I Found the --> "<<num<<" is going to be deleted"<<endl;
nextptr = previousptr;
//nextptr = nextptr->next;
}
nextptr = nextptr->next;
}
delete nextptr;
delete previousptr;
}
I tried in all different ways but always get accesss violation error . Please give me conceptual and code hints if possible . thanks
the code is in win32 Vs2010 app
What happens after the while loop end. Well, nextptr == NULL. delete NULL == problem.
Try this:
node *previous = nullptr, *current = head, *temp;
while(current){
temp = current->next;
if(abs(current->data - num) < MARGIN_OF_ERROR){
if (previous){
previous->next = current->next;
} else {
head = current->next;
}
delete current;
} else{
previous = current;
}
current = temp;
}
something like this (pseudo-code)
public void removeData( double data )
{
if ( this.node == null ){ return; }
if ( this.node->data == data ){
this.node = this.node.node;
}
this.node.removeData( data );
}
Two issues I can trace:
You should never use operator== to check equality of two floating
point numbers, there is an issue with floating point arithmetic -
they are not exact, and result might not be as you expect [not a solution to your problem but definetly an issue]
Your previousptr and nextptr are the same thing [they are both pointing at the same address!]. You should modify previousptr before the current iteration. [right before nextptr = nextptr->next;]. Because of it, when you delete nextptr and later set:
nextptr = previousptr;
nextptr = nextptr->next;
You are actually accessing the element you just deleted, which causes your illegal access.
Probably this can be done through recursion, but here is a moving pointer solution:
void removenumber(node **head, int value)
{
node * current;
node * prev;
node * tmp;
current = (*head);
if ( current == NULL) return;
prev = current;
current = current->next;
while( current!= NULL && current->next != NULL)
{
if ( current->data == value)
{ //remove current
tmp = current->next;
prev->next = current->next;
free(current);
current = tmp;
//previous is the same
continue;
}
current = current->next;
prev = prev->next;
}
// now current->next != NULL check it
if(current!=NULL) //what is current was deleted?
{
if(current->data == value )
{
prev->next = NULL;
free(current);
}
}
if ( (*head)->data == value) //remove head
{
tmp = (*head)->next;
free(*head);
*head = tmp;
}
}