I'm attempting to write a function to see whether or not there are more nodes to search through in the linked list, and what I have so far gives me a seg fault. Any ideas on what I need to change?
Iterator class:
bool Iterator::hasNext(){
Node* temp = current->getNext();
if(temp == NULL){
return(false);
}
else{
return(true);
}
List Class:
void List::addFirst(void* obj)
{
Node* newNode = new Node(obj);
newNode->setNext(head);
head = newNode;
}
Node Class:
Node* Node::getNext()
{
return(next);
}
Main class:
List list1;
for(int i = 0; i < 4; i++) {
list1.addFirst(stars[i]);
}
Iterator itr(&list1);
while(itr.hasNext()) {
std::cout << ((char*)itr.get()->getItem())
<< std::endl;
itr.advance();
}
I am not sure about it but you can
Try
//directly accessing the next and comparing
return if(current->getNext() == NULL)
directly without storing it in a separate temp node .
Related
My project is a bubble sort system for doubly linked list.
I am trying to sort elements of doubly linked list (which are objects) by Date.
I used pointer-based sort because I do not want to change the data of pointers.
The problem is my code can (I think efficiently) sort the linked list. But in the end, when I try to print objects of linked list, my head is not in place where it should be. Could you help me?
struct DoubleNode *DoubleDynamic::swap( DoubleNode *pointer1, DoubleNode *pointer2) {
DoubleNode* temp=pointer2->next;
pointer2->next=pointer1;
pointer2->prev=pointer1->prev;
pointer1->next=temp;
pointer1->prev=pointer2;
return pointer2;
}
void DoubleDynamic::sort(int size)
{
DoubleNode* temp;
DoubleNode* current;
bool sorting;
if (head==NULL)
{
return;
}else
{
for (int i = 0; i <= size; ++i)
{
sorting= false;
temp=head;
for (int j = 0; j < size-1-i; ++j)
{
DoubleNode *employee1=temp;
DoubleNode *employee2=employee1->next;
if (employee2!=NULL)
{
if (employee1->data->getAppointment().operator>(employee2->data->getAppointment()))
{
temp = swap(employee1,employee2);
sorting= true;
}
temp= temp->next;
}
}
if (!sorting)
{
break;
}
}
}
current=head;
while (current->prev!=NULL)
{
current=current->prev;
}
head=current;
}
void DoubleDynamic::display()
{
struct DoubleNode *trav;
trav=head;
if (trav==NULL)
{
cout<<"Liste boş yaa"<<endl;
}
while (trav != NULL)
{
cout<<*(trav->data)<<endl;
trav=trav->next;
}
cout<<endl;
}
The problem is that when you swap the head pointer, you don't update head to refer to the new head node.
One way to address this is after you do the swap, you should check to see if the head pointer should be updated.
temp = swap(employee1,employee2);
if (employee1 == head)
head = temp;
Alternatively, in swap, if the new prev pointer assigned in pointer2->prev=pointer1->prev; is NULL then update the head (because the head node does not have a previous node).
if ((pointer2->prev=pointer1->prev) == nullptr)
head = pointer2;
I am trying to finish up a assignment for my data structures c++ class. I have to define a double linked list of functions(like insert() size() remove() ) that was provided by my instructor. The instructor also includes the main file which runs tests on my code to see if it works.
I'm receiving his error message:
* Starting dlist tests *
Checking empty list...
FAILED: size of empty list is != 0.
I tried to rewrite the definition of the size() and insert() function and Im not understanding why im getting his error.
my instructors test code:
bool test_empty() {
std::cout << "Checking empty list...\n";
dlist e;
if(!verify(e))
return false;
if(e.size() != 0) {
std::cout << "FAILED: size of empty list is != 0.\n";
return false;
}
if(!e.empty()) {
std::cout << "FAILED: empty list is not .empty().\n";
return false;
}
return true;
}
my code for implementations:
void insert(node *previous, int value){
if(previous == nullptr){
node* n = new node;
n->value = value;
n->prev = previous;
n->next = nullptr;
return;
}
node* n = _head; //made a pointer to start at the head
while( n!= previous )//make n go down the list until it hits previous
{n = n->next;}
node* store_next = n->next; //store the address of the prev pointer of the next node
node* a = new node;//create the node that will be inserted
a->value = value;
n->next = a;// the pointer n points to the new node
a->prev = n; //the prev in the new node points to the previous
a->next = store_next; //the next in the new node points to the next node
store_next->prev = a; //the next node's prev points to the new inserted node
}
int size() const{
node* n = _head;
int size = 0;
while(n != nullptr){
size++;
n = n -> next;
}
return size;
}
Heres my default constructor and double linked list struct that my professor requires I use
class dlist {
public:
dlist() {
}
struct node {
int value;
node* next;
node* prev;
};
I'm writing a copy constructor that copies for example S to R; Set R(S);. S is a sorted singly linked list containing some ints (with a dummy node in the beginning).
Set::Set (const Set &source)
{
Node* sourceNode = source.head->next;
head = new Node(0, nullptr);
Node* nodeHead = source.head->next;
Node* p;
if (!sourceNode) {
std::cout << "Empty !" << endl;
}
else{
while (nodeHead) {
for (p=sourceNode; p->next; p=p->next) {
;
}
head->next = new Node(nodeHead->value,nullptr);
head = head->next;
nodeHead = nodeHead->next;
}
}
}
Right now it crashes and if i remove head = head->next; it will set S to { 5 }.
This is the constructor:
class Node
{
public:
Node (int, Node*);
private:
int value;
Node* next;
};
Why doesn't this work? This is my first experience with pointers so keep that in mind please.
Let's assume you have a function that adds to the end of the linked list. The copy constructor in this case would be very simple:
Set::Set (const Set &source) : head(0)
{
Node* sourceNode = source.head;
while (sourceNode != NULL )
{
addToList(sourceNode->value);
sourceNode = sourceNode->next;
}
}
The addToList would be the function that adds a node to the back of the list. All the copy constructor has to do is start off with an empty list, and in a loop, add items from the source list until the number of items in the source list is exhausted. This method, given that the addToList function is coded correctly, is guaranteed to work, and avoids code duplication.
This is the easiest way to implement the copy constructor. If you have no function that adds to the back of the list, now would be the good time to add it since you will need to to have such a function in any event.
Here is some code
LinkList(LinkList const & temp) // Copy constructor
{
this->head = 0; // calling list head
Node* tempHead = temp.head; /*For temprory store of head of link list*/
while (tempHead != 0)
{
this->insertAtEnd(tempHead->data);
tempHead = tempHead->next;
}
}
void insertAtEnd(int val)
{
Node* temp = new Node;
temp->data = val;
temp->next = 0;
Node* curr = this->head;
if (curr != 0)
{
while (curr->next != 0)
{
curr = curr->next;
}
curr->next = temp;
}
else
{
this->head = temp;
}
}
#include <iostream>
#include<string>
using namespace std;
struct nodeType
{
int info;
nodeType *next;
};
class linkedListType
{
private:
nodeType *first, *last;
int length;
public:
linkedListType()//constructor
{
first = last = NULL;
length = 0;
}
void print() // normal print
{
nodeType * current = first;
while (current != NULL)
{
cout << current->info <<" ";
// update statement
current = current ->next;
}
}
void insertEnd(int item) //insert item to the end of the list
{ // forward insertion
nodeType* newNode = new nodeType;
newNode ->info = item;
if (length == 0)
{
first = last = newNode;
newNode->next = NULL;
}//if
else
{
last->next = newNode;
last = newNode;
newNode->next = NULL;
}// else
length++;
}
}
void clearList()
{
nodeType * current;
while ( first != NULL)
{
current = first;
first = first->next;
delete current;
length--;
}// while
~linkedListType() //destroctor
{
clearList();
}
> `
//
Blockquote i cant write this method emplement please anyone help me and explane why ////////////////////////////////////////////////////////////////////
/this method. can anyone help ma to write it to me and explan why/
////////////////////////////////////////////////////////////////////
`
void printReverse() /*this is the function that i cant understand it or complete it. this function print elements in the list in reverse*/
{
nodeYype* current=last ,*newnode =new nodType ;
for(int i=length;i>=0;i--)
//i cant complete this method
}
};
void main()
{
linkedListType list1;
list1.insertEnd(12); //insert item
list1.insertEnd(25);//insert item
list1.insertEnd(18);//insert item
list1.insertEnd(37);//insert item
list1.insertEnd(60);//insert item
list1.insertEnd(100);//insert item
list1.insertEnd(37);//insert item
list1.insertEnd(37);//insert item
list1.insertEnd(37);//insert item
list1.insertEnd(60);//insert item
list1.insertEnd(25);//insert item
list1.insertEnd(100);//insert item
list1.insertEnd(25);//insert item
cout <<"Printing the linked list elements\n";
list1.print();
cout <<"\nPrinting the list elements in reverse order\n";
list1.printReverse();
}
void nodeType::PrintListReverse()
{
if (next)
next->PrintListReverse();
std::cout << info << std::endl;
}
Recursively find the end of the list, printing on return.
(I'm only enabling you because I'm bored)
Alternatively:
void linkedListType::PrintList()
{
std::vector<int> info(length);
nodeType* curNode = first;
for (int i = 0; curNode != NULL; i++, curNode = curNode->next)
{
info[i] = curNode->info;
}
for (int i = length-1; i >=0; i--)
{
std::cout << info[i] << std::endl;
}
}
If you can write a recursive function to traverse the list in proper order, printing it in reverse order is a snap.
There are two possibilities. Either to write a recursive function or rebuild your list in the reverse order. That is before printing the list you either create a new list on the base pf existent or rebuild the original list itself.
You already have a loop that decrements i from length to 0. Based on i, you can traverse the list and print the node that you reached. Fine tune for off by 1 errors so that you actually print from last to first and don't print when the list is empty.
Does this look right? I mean I am trying to implement the delete function.
Node* BST::findNode(int tofind) {
Node* node = new Node;
node = root;
while (node != NULL) {
if (node->val == tofind) {
return node;
} else if (tofind < node->val) {
node = node->left;
} else {
node = node->right;
}
}
}
Here is the delete, it's not even close to done but,
void BST::Delete(int todelete) {
// bool found = false;
Node* toDelete = new Node();
toDelete=findNode(todelete);
if(toDelete->val!=NULL) {
cout << toDelete->val << endl;
}
}
This causes a segmentation fault just running that, any ideas?
The main problem with findNode() is that you never return the node that you've found. That's why you're getting the segfault.
Also, in deleteNode() you should check whether findNode() has returned NULL. And of course you also need to code up the rest of the deletion logic.
Finally, the two new Node allocations are unnecessary and are leaking memory.
oh wait it's because in delete I should have done:
if(toDelete!=NULL) {
cout << toDelete->val << endl;
}
before it was
if(toDelete->val!=NULL)