Access Violation Reading Location: Linked List c++ - c++

I am trying to do a linked list of int values. I add 3 int values to list, and I print them but my problem after print the 3 values, the program goes back in to print function to print a 4th one because (tempNode != NULL) gives true but it should be NULL after printing 3 values, so it gives me access violation reading error in the print method at cout << "index " << size-- << ", value: "<< tempNode->num << endl;
It is going beyond my list nodes, but I have no idea where am doing wrong.
Please help, 2 days am trying to figure this out.
code below.
IntList::IntList()
{
first = NULL;
last = NULL;
size = 0;
}
IntList::Node::Node(const int& info, Node* next = NULL)
{
num = info;
next = next;
}
IntList::~IntList()
{
Node* tempNode = first;
while ( tempNode != NULL )
//for(int i = 0; i < size; i++)
{
Node* nextNode = tempNode->next;
delete tempNode;
tempNode = nextNode;
}
first = last = NULL;
size = 0;
}
IntList::IntList(const IntList& wl)
{
cout << "here word list copy conts " << endl;
first = last = NULL;
size = wl.size;
if(wl.first != NULL){
Node* tempNode = wl.first;
for(int i = 0; i < wl.size; i++)
{
addLast(tempNode->num);
tempNode = tempNode->next;
}
}
}
IntList& IntList::operator = (const IntList& wl)
{
cout << "here word list =" << endl;
if(this == &wl)
return *this;
Node* tempNode = first;
while ( tempNode != NULL )
{
Node* nextNode = tempNode->next;
delete tempNode;
tempNode = nextNode;
}
first = NULL;
last = NULL;
if(wl.first != NULL)
{
for(int i = 0; i < wl.size; i++)
{
addLast(tempNode->num);
tempNode = tempNode->next;
size++;
}
}
return *this;
}
void IntList::addFirst(int& winfo)
{
Node* firstNode = new Node(winfo);
//Node firstNode(winfo);
if(first == NULL)
{
first = last = firstNode;
}
else
{
firstNode->next = first;
first = firstNode;
}
//increment list size
size++;
}
void IntList::print(ostream& out)
{
Node* tempNode = first;
while ( tempNode != NULL )
{
out << "\t";
cout << "index " << size-- << ", value: "<< tempNode->num << endl;
tempNode = tempNode->next;
}
}

The next parameter of the Node constructor shadows its next member, so next = next is assigning to the parameter.
Rename one of them.
Also, don't modify size while you're printing.

Related

How to sort doubly linked list in c++ without swapping data, only transferring (entries) nodes

I have got a problem in the sorting method of my linked list. I need to sort nodes in a doubly linked list by transferring links of nodes (entries of nodes). The method is stopped due to nullptr in the last node.
I do not know how to solve this problem. I tried a lot of variants, but no one was successful.
#include "DlinkedList.h"
// Node constructor
Node::Node()
{
this->rhetorician = NULL;
this->prev = NULL;
this->next = NULL;
}
// Node destructor
Node::~Node()
{
}
// List constructor
DlinkedList::DlinkedList()
{
this->length = 0;
this->head = NULL;
}
// Method for adding node at the end
void DlinkedList::appendNode(Rhetorician* rhetorician)
{
if (this->head == NULL) {
Node *new_node = new Node();
new_node->rhetorician = rhetorician;
this->head = new_node;
}
else {
Node *last_node = NULL;
for (Node *node_ptr = this->head; node_ptr != NULL; node_ptr = node_ptr->next)
{
last_node = node_ptr;
}
Node *new_node = new Node();
new_node->rhetorician = rhetorician;
last_node->next = new_node;
new_node->prev = last_node;
}
this->length++;
}
// Method for printing nodes
void DlinkedList::printNodes()
{
for (Node *node_cur = this->head; node_cur != NULL; node_cur = node_cur->next)
{
node_cur->rhetorician->printer();
cout << "---------------------------------------------------------------------------------------------------" << endl;
}
cout << endl << "##################################################################################################\n" << endl;
}
// Method for getting length
int DlinkedList::getLenght()
{
return this->length;
}
// Method for deleting node
void DlinkedList::remove(string name)
{
Node* logout_node = NULL;
for (Node* node_cur = this->head; node_cur != NULL; node_cur = node_cur->next)
{
if (node_cur->rhetorician->name == name)
{
logout_node = node_cur;
}
}
if (this->head != NULL || logout_node != NULL)
{
if (this->head == logout_node)
{
this->head = logout_node->next;
}
if (logout_node->next != NULL)
{
logout_node->next->prev = logout_node->prev;
}
if (logout_node->prev != NULL)
{
logout_node->prev->next = logout_node->next;
}
delete logout_node->rhetorician;
delete logout_node;
this->length--;
}
}
// Method for finding node
void DlinkedList::find(string name)
{
bool ver = false;
Node *n = NULL;
for (Node* node_cur = this->head; node_cur != NULL; node_cur = node_cur->next)
{
if (node_cur->rhetorician->name == name)
{
ver = true;
n = node_cur;
}
}
if (ver)
{
n->rhetorician->printer();
}
else
{
cout << "Rhetorician was not found!";
}
}
// Method for sorting nodes
void DlinkedList::sort()
{
int count = this->getLenght();
Node *tmp, *current;
int i, j;
for (i = 1; i < count; i++)
{
current = this->head;
for (j = 0; j <= count - i - 1; j++)
{
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient)
{
before = current->prev;
after = current->next;
if (before != NULL) {
before->next = after;
}
current->next = after->next;
current->prev = after;
after->next = current;
after->prev = before;
}
tmp = current;
current = current->next;
}
}
}
// List destructor
DlinkedList::~DlinkedList()
{
Node *next_node = NULL;
for (Node *node_cur = this->head; node_cur != NULL; node_cur = next_node)
{
next_node = node_cur->next;
delete node_cur->rhetorician;
delete node_cur;
}
this->head = NULL;
this->length = 0;
}
Main:
#include <iostream>
#include "DlinkedList.h"
#include <fstream>
#include <vector>
#include <sstream>
// Namespace
using namespace std;
// Parser of line to vector array
vector<string> split(string strToSplit, char delimeter)
{
stringstream ss(strToSplit);
string item;
vector<string> splittedStrings;
while (getline(ss, item, delimeter))
{
splittedStrings.push_back(item);
}
return splittedStrings;
}
// File loader
void read_file(const char *name, DlinkedList *list)
{
// Variable for loading line
string line;
{
// Create relation
ifstream file(name);
// Check if file exists
if (file)
{
// Check if file is empty
if (!(file.peek() == ifstream::traits_type::eof()))
{
// Read data from file and put into LinkedList
while (getline(file, line)) {
list->appendNode(new Rhetorician(split(line, ';')[0], split(line, ';')[1],
split(line, ';')[2], stoi(split(line, ';')[3])));
}
}
// Close file
file.close();
}
}
}
// Main method
int main()
{
// Create instance of doubly linked list
DlinkedList *list = new DlinkedList();
// Read file and push data into list
read_file("seznam_enumat.txt", list);
// Print all loaded rhetoricians behind added own one
cout << "\nAll rhetoricians from file:" << endl;
cout << "##################################################################################################\n" << endl;
list->printNodes();
// Append other rhetoricians
list->appendNode(new Rhetorician("Cain", "Foster", "Structural and molecular virology", 7));
list->appendNode(new Rhetorician("Stacy", "Algar", "Dept of microbiology and immunology", 5));
list->appendNode(new Rhetorician("Oded", "Philander", "Experimental plasma physics", 3));
list->appendNode(new Rhetorician("Shay", "Rimon", "Experimental plasma physics", 10));
// Sort rhetoricians in list
list->sort();
// Delete rhetorician by name
//list->remove("Stacy");
// Finder of rhetorician
cout << "\nFound rhetorician:" << endl;
cout << "##################################################################################################\n" << endl;
list->find("Shay");
// Print all sorted rhetoricians
cout << "\nAll rhetoricians:" << endl;
cout << "##################################################################################################\n" << endl;
list->printNodes();
// Destruct list
delete list;
// Check if user click any key
getchar();
return 0;
}
Rhetorician:
#include "Rhetorician.h"
Rhetorician::Rhetorician(string name, string surname, string contribution, int coefficient)
{
this->name = name;
this->surname = surname;
this->contribution = contribution;
this->coefficient = coefficient;
}
void Rhetorician::printer()
{
// Name
cout << "Name:" << endl;
cout << this->name << endl;
// Surname
cout << "Surname:" << endl;
cout << this->surname << endl;
// Contribution
cout << "Contribution:" << endl;
cout << this->contribution << endl;
// Coefficient
cout << "Coefficient:" << endl;
cout << this->coefficient << endl;
}
The main issue is in sort(). It is not handling the pointers correctly.
Take a short example, 3 -> 2 -> 1 and you will get it.
Here is the corrected code with unnecessary variables removed:
void DlinkedList::sort() {
int count = this->getLenght();
Node *current;
int i, j;
for (i = 1; i < count; i++) {
current = this->head;
for (j = 0; j <= count - i - 1; j++) {
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient) {
before = current->prev;
after = current->next;
if (before != nullptr) {
before->next = after;
} else {
// if before = null, it is the head node
this->head = after; // In case before pointer is null, after pointer should be the new head
}
current->next = after->next;
current->prev = after;
if (after->next != nullptr) {
after->next->prev = current; // prev pointer of after->next should be set to current.
}
after->next = current;
after->prev = before;
} else {
current = current->next; // Go to next node only if current->rhetorician->coefficient > current->next->rhetorician->coefficient condition is false.
}
}
}
}
The upwardly sorted list is working super but when I tried to sort the list downwardly only change the character > for < it is not working. Must be changed before node and after node?
// Zero or one element, no sort required.
if (this->head == NULL) return;
if (this->head->next == NULL) return;
// Force initial entry.
int swapped = 1;
while (swapped) {
// Flag as last time, then do one pass.
swapped = 0;
this->current = this->head;
while (this->current->next != NULL) {
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient) {
swapped = 1;
before = current->prev;
after = current->next;
if (before != NULL) {
before->next = after;
}
else {
// if before = null, it is the head node
this->head = after; // In case before pointer is null, after pointer should be the new head
}
current->next = after->next;
current->prev = after;
if (after->next != NULL) {
after->next->prev = current; // prev pointer of after->next should be set to current.
}
after->next = current;
after->prev = before;
}
current = current->next;
}
}// Zero or one element, no sort required.
if (this->head == NULL) return;
if (this->head->next == NULL) return;
// Force initial entry.
int swapped = 1;
while (swapped) {
// Flag as last time, then do one pass.
swapped = 0;
this->current = this->head;
while (this->current->next != NULL) {
Node *before, *after;
if (current->rhetorician->coefficient > current->next->rhetorician->coefficient) {
swapped = 1;
before = current->prev;
after = current->next;
if (before != NULL) {
before->next = after;
}
else {
// if before = null, it is the head node
this->head = after; // In case before pointer is null, after pointer should be the new head
}
current->next = after->next;
current->prev = after;
if (after->next != NULL) {
after->next->prev = current; // prev pointer of after->next should be set to current.
}
after->next = current;
after->prev = before;
}
current = current->next;
}
}

C++ Rebuilding Singly Linked List Links

I'm attempting to build a priority queue using a singly linked list. The idea is that I always store the minimum int x inside my Node* head. When the deleteMin() method is called. It should return the minimum value (head->x), and also update the head to the next lowest value in the list.
The problem that I seem to be having is updating the links once a new lowestNode has been found.
SLList.hpp
const int deleteMin() {
int returnVal = this->head->x;
// we need to find the next lowest in the list and update our head, then relink the list.
// first update our head to the next of the current head
this->head = this->head->next;
cout << "head now: " << this->head->x << endl;
// iterate through our nodes searching for a smaller value
Node* currentNode = this->head;
Node* nextNode = NULL;
Node* lowestNode = NULL;
Node* prevNode = NULL;
// Node* prevHead = NULL;
// Node* nextHead = NULL;
while(currentNode != NULL) {
if (currentNode->next->x < this->head->x) {
nextNode = currentNode->next->next;
cout << "nextNode: " << nextNode->x << endl;
lowestNode = currentNode->next;
cout << "lowestNode: " << lowestNode->x << endl;
prevNode = currentNode;
cout << "prevNode: " << prevNode->x << endl;
// prevHead = this->head;
// cout << "prevHead: " << prevHead->x << endl;
// nextHead = this->head->next;
// cout << "nextHead: " << nextHead->x << endl;
// update links
lowestNode->next = this->head->next;
currentNode = this->head;
currentNode->next = nextNode;
this->head = lowestNode;
} else {
currentNode = currentNode->next;
}
}
// decrement the size
this->_size--;
// return the minVal
return returnVal;
}
while(currentNode != NULL && currentNode->next!=NULL) //here you need check for currectNode->next also for NULL condition
{
if (currentNode->next->x < this->head->x) {
nextNode = currentNode->next->next;
cout << "nextNode: " << nextNode->x << endl;
lowestNode = currentNode->next;
cout << "lowestNode: " << lowestNode->x << endl;
//here storing previous node is of no use except for debugging
prevNode = currentNode;
cout << "prevNode: " << prevNode->x << endl;
// update links- here you need to first remove the lowest node from its postion
currentNode->next=nextNode;
//and then add lowest node a the front
lowestNode->next = this->head->next;
this->head = lowestNode;
} else {
currentNode = currentNode->next;
}
}
One problem that I realized was that depending on where the node that contains the lowest int x. If head is directly linked a lower node, then the relinking needed to be a little different than if a lower node was found in the middle of the list.
#ifndef SLLIST_H
#define SLLIST_H
using namespace std;
class SLList
{
struct Node {
int x;
Node *next;
};
private:
int _size;
public:
Node* head; // used to store minimum value of a Node's x
Node* tail;
SLList() :
_size(0),
head(NULL),
tail(NULL) {
}
int size() const {
return this->_size;
}
const int add (const int x) {
// create new node
Node* newNode = new Node();
newNode->x = x;
if (this->_size == 0) {
this->head = newNode;
this->tail = newNode;
} else {
if (newNode->x < this->head->x) {
// update head to new lowest and relink nodes
newNode->next = this->head;
this->head = newNode;
} else {
this->tail->next = newNode;
this->tail = newNode;
}
}
// update list size
this->_size++;
return x;
}
const int deleteMin() {
if (this->_size == 0) return -1;
int returnVal = this->head->x;
cout << "removing min val: " << returnVal << endl;
// we need to find the next lowest in the list and update our head, then relink the list.
// first update our head to the next of the current head
this->head = this->head->next;
// iterate through our nodes searching for a smaller value
Node* currentNode = this->head;
Node* lowestNode = NULL;
for(int i = 0; i < this->_size - 1; i++) {
if (currentNode->next->x < this->head->x) {
lowestNode = currentNode->next;
if (currentNode == this->head) {
cout << "current->next is next to head" << endl;
// only need to update 2 nodes
this->head->next = currentNode->next->next;
lowestNode->next = this->head;
this->head = lowestNode;
currentNode = currentNode->next;
} else {
// update three nodes
cout << "current->next has neighbours" << endl;
// Example scenario
// 3 // nextTo5
// 5 // nextTo4
// 4 // nextTo2
// 2 // nextToNull
// == turns into ==
// 2 // nextTo5
// 5 // nextTo4
// 4 // nextTo3
// 3 // nextToNull
lowestNode->next = this->head->next;
currentNode->next = this->head;
this->head = lowestNode;
currentNode = currentNode->next;
}
} else {
currentNode = currentNode->next;
}
}
// decrement the size
this->_size--;
// return the minVal
return returnVal;
}
const void printList() const {
Node* tmp = this->head;
cout << "printing list... " << endl;
for(int i = 0; i < this->_size; i++) {
cout << tmp->x << endl;
tmp = tmp->next;
}
}
};
#endif // SLLIST_H
Perhaps I should actually use the tail somehow, but currently, I don't really use it for much.

C++ Linked List list_copy_front function confusion

I've been struggling with this last function (list_copy_front). The function is for a linked list, it is supposed to return the value of the head pointer for a new list that contains copies of the first n nodes that the source pointer points to. Also if there is less than n nodes in the source then just copy all. Currently, when I run it as is I get a nasty Segmentation Fault SIGSEGV error. The debugger says the error happens at "Node *cursor = source_ptr-> link; Any help would be greatly appreciated, thank you.
Here is some relevant info,
struct Node
{
typedef int Item;
Item data;
Node *link;
};
void list_tail_attach(Node*& head_ptr, const Node::Item& entry);
Node* list_copy_front(Node* source_ptr, size_t n);
void list_tail_attach(Node*& head_ptr, const Node::Item& entry)
{
Node *last = new Node;
last->data = entry;
last->link = NULL;
if(head_ptr == NULL)
{
head_ptr = last;
}
else
{
Node *temp = new Node;
temp = head_ptr;
while(temp->link != NULL)
{
temp = temp->link;
}
temp->link = last;
}
}
Node* list_copy_front(Node* source_ptr, size_t n)
{
Node *new_head_ptr = new Node;
Node *cursor = source_ptr->link;
size_t i = 0;
for(i = 0; i < n; i++)
{
list_tail_attach(new_head_ptr, cursor->data);
cursor = cursor->link;
}
return new_head_ptr;
}
Here's the Main test for the function
int test4()
{
Node* list = NULL; // an empty list
Node* copy = NULL;
copy = list_copy_front(list, 3);
if(copy != NULL)
{
cout << "list_copy_front function doesn't work for copying empty list\n";
return 0;
}
for(int i = 1; i <= 4; i++)
list_tail_attach(list, i);
// list contains 1, 2, 3, 4
copy = list_copy_front(list, 3);
if(list_length(copy) != 3 || copy->data != 1 || copy->link->data != 2 || copy->link->link->data != 3 )
{
cout << "list_copy_front function doesn't work\n";
return 0;
}
copy->link->data = 100;
if(list->link->data == 100)
{
cout << "list_copy_front function doesn't work.\n";
return 0;
}
list_clear(copy);
copy = list_copy_front(list, 6);
if(list_length(copy) != 4)
{
cout << "list_copy_front function doesn't work\n";
return 0;
}
cout << "list_copy_front passes the test\n";
list_clear(list);
for(int i = 1; i <= 3; i++)
list_head_insert(list, i);
// list contains 3, 2, 1
list_copy(list, copy);
if(list_length(copy) != 3 || copy->data != 3 || copy->link->data != 2 || copy->link->link->data != 1 )
{
cout << "list_copy function doesn't work\n";
return 0;
}
cout << "list_copy function passes the test\n";
return 2;
}
Edit 3
So far here's what I'm working with I appreciate the comments so far it's just not quite working out. Which is probably my fault for not explaining better.
void list_tail_attach(Node*& head_ptr, const Node::Item& entry)
{
Node *last = new Node; // Creates new Node
last->data = entry; // Points last to data
last->link = NULL;
if(last == NULL)
{
return;
}
if(head_ptr == NULL)
{
head_ptr = last;
}
else
{
Node *temp = head_ptr;
while(temp->link != NULL)
{
temp = temp->link;
}
temp->link = last;
}
}
Node* list_copy_front(Node* source_ptr, size_t n)
{
if(source_ptr == NULL)
{
return NULL;
}
Node *new_head_ptr = new Node;
Node *cursor = source_ptr;
size_t i = 0;
while(cursor!= NULL && i < n)
{
list_tail_attach(new_head_ptr, cursor->data);
cursor = cursor->link;
i++;
}
return new_head_ptr;
}
I am not allowed to change the way the function takes it's input so, that's why I left Node *last.
I left list_tail_attach(new_head_ptr, cursor->data) because without it I get an invalid conversion error. However when I run the above code I still receive an SIGSEGV error for while(temp->link != NULL) in list_tail_attach and on list_tail_attach(new_head_ptr, cursor->data); in list_copy_front.
Thank you if you are able to comment further
The first test case
Node* list = NULL; // an empty list
Node* copy = NULL;
copy = list_copy_front(list, 3);
gives Node* source_ptr == NULL and expects your function to handle it gracefully.
The function code soon tries to dereference NULL
Node *cursor = source_ptr->link;
The result is a segfault.
First is list_tail_attach, this function I assumed to be attaching an existing Node into a linked list. If the linked list is null then the Node become the head
void list_tail_attach(Node *& head_ptr, Node *& entry)
{
if (entry == NULL) {
return;
}
if (head_ptr == NULL)
{
head_ptr = entry;
}
else
{
Node *temp = head_ptr;
while (temp->link != NULL)
{
temp = temp->link;
}
temp->link = entry;
}
}
I changed the entry into a reference to a pointer to made it easier.
Ok, now move on to the list_copy_front
Node * list_copy_front(Node* source_ptr, size_t n)
{
if (source_ptr == NULL) {
return NULL;
}
Node * new_head_ptr = new Node;
Node * cursor = source_ptr;
size_t i = 0;
while(cursor != NULL && i < n){
list_tail_attach(new_head_ptr, cursor);
cursor = cursor->link;
i++;
}
return new_head_ptr;
}
You have to guard the source_ptr in case it is null.
To attach a new Node
for (int x = 0; x < 5; x++) {
Node * tmp = new Node();
tmp->data = x;
tmp->link = NULL;
list_tail_attach(list, tmp);
}
My professor helped me out with the correct solution. For anyone who views this in the future...
Node* list_copy_front(Node* source_ptr, size_t n)
{
if(source_ptr == NULL) // Takes care of NULL case
{
return NULL;
}
Node *new_head_ptr = NULL; // Creates new head and ensures NULL
Node *cursor = source_ptr; // Sets temp Node = to source
size_t i = 0; // Initializes temp variable
while(cursor!= NULL && i < n) // Loop that continues while n is bigger than i and it is not NULL
{
list_tail_attach(new_head_ptr, cursor->data);
cursor = cursor->link; // Attaches to new list
i++; // Increases count
}
return new_head_ptr;
}
The line that needed to be changed was
Node * new_head_ptr = new Node;
to
Node * new_head_ptr = NULL;

Linked List insertion/deletion

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* head = NULL;
int size;
Node* tail = NULL;
void printLinkedList() {
Node *search = head;
if (head == NULL) {
cout << "linkedlist is empty" << endl;
}
else {
while (search != NULL){
cout << search->data << endl;
search = search->next;
}
}
}
int sizeLinkedList() {
size = 1;
Node* current = head;
while (current->next != NULL) {
current = current->next;
size = size + 1;
}
cout << size << endl;
return size;
}
Node *getNode(int position){
Node *current = head;
for (int i = 0; i<position; i++)
{
current = current->next;
}
return current;
}
void appendNode(int n) {
Node *newNode = new Node; //creating new node
newNode->data = n;
newNode->next = NULL;
if (head == NULL)
{
head = newNode;
return;
}
else {
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
void insertNode(int n, int position) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = NULL;
int size = sizeLinkedList();
if (position = 0){
if (head == NULL) {
head = newNode;
}
else{
newNode->next = head;
head = newNode;
}
}
else if (position == size) {
appendNode(n);
}
else {
Node *prevNode = getNode(position-1);
Node *nextNode = getNode(position);
prevNode->next = newNode;
newNode->next = nextNode;
}
}
void deleteNode(int position) {
Node *currentNode;
int size = sizeLinkedList();
if (size == 0) {
return;
}
if (position == 0) {
currentNode = head->next;
head = currentNode;
}
else if (position == size-1) {
getNode(position - 1)->next = NULL;
delete getNode(position);
}
else {
getNode(position - 1)->next = getNode(position+1);
delete getNode(position);
}
}
//making a dynamic array only via pointers in VC++
void makeArray() {
int* m = NULL;
int n;
cout << "how many entries are there?"<<endl;
cin >> n;
m = new int[n];
int temp;
for (int x = 0; x < n; x++){
cout << "enter item:"<< x+1<< endl;
cin >> temp;
*(m + x) = temp;
}
for (int x = 0; x < n; x++){
cout << x+1 + ":" << "There is item: "<<*(m+x) << endl;
}
delete[]m;
}
int main() {
int x;
//makeArray();
appendNode(1);
appendNode(2);
appendNode(32);
appendNode(55);
appendNode(66);
//insertNode(2, 0);
printLinkedList();
deleteNode(3);
printLinkedList();
sizeLinkedList();
cin >> x;
}
Im just trying to code a Linked List with a couple of functions for practice
My Delete function, the last else statement isnt working, and logically I cant figure out why,
as for my insert function none of the statements are working, not even at head or position 0. However appending items, returning size, printing the list, deleting the first and last elements works.
thanks!
sizeLinkedList won't work correctly if the list is empty (it cannot return 0)
you are using size as different variables at different scopes (at main scope, and within deleteNode). This is pretty confusing although not strictly wrong.
in deleteNode, this sequence won't work:
else if (position == size-1) {
getNode(position - 1)->next = NULL;
delete getNode(position);
}
setting the next pointer on the node prior to position to NULL will interfere with the attempt to getNode(position) in the very next line, because it traverses the list based on next. The fix is to reverse these two lines.
Likewise, your last sequence in deleteNode won't work for a similar reason, because you are modifying the next pointers:
else {
getNode(position - 1)->next = getNode(position+1);
delete getNode(position); // this list traversal will skip the node to delete!
}
the solution here is like this:
else {
currentNode = getNode(position);
getNode(position - 1)->next = getNode(position+1);
delete currentNode;
}
I've also re-written the insertNode function incorporating the comment provided by #0x499602D2 .
Here's a modified version of your code that has your current sequence in main fixed:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* head = NULL;
int size = 0;
Node* tail = NULL;
void printLinkedList() {
Node *search = head;
if (head == NULL) {
cout << "linkedlist is empty" << endl;
}
else {
while (search != NULL){
cout << search->data << endl;
search = search->next;
}
}
}
int sizeLinkedList() {
size = 0;
if (head->next != NULL){
size = 1;
Node* current = head;
while (current->next != NULL) {
current = current->next;
size = size + 1;
}
}
cout << size << endl;
return size;
}
Node *getNode(int position){
Node *current = head;
for (int i = 0; i<position; i++)
{
current = current->next;
}
return current;
}
void appendNode(int n) {
Node *newNode = new Node; //creating new node
newNode->data = n;
newNode->next = NULL;
size++;
if (head == NULL)
{
head = newNode;
return;
}
else {
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
void insertNode(int n, int position) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = NULL;
if (position == 0){
newNode->next = head;
head = newNode;
}
else if (position == sizeLinkedList()) {
appendNode(n);
}
else {
Node *prevNode = getNode(position-1);
Node *nextNode = getNode(position);
prevNode->next = newNode;
newNode->next = nextNode;
}
}
void deleteNode(int position) {
Node *currentNode;
int my_size = sizeLinkedList();
if ((my_size == 0) || (position > my_size)) {
return;
}
if (position == 0) {
currentNode = head->next;
head = currentNode;
}
else if (position == size-1) {
delete getNode(position);
getNode(position - 1)->next = NULL;
}
else {
currentNode = getNode(position);
getNode(position - 1)->next = getNode(position+1);
delete currentNode;
}
}
//making a dynamic array only via pointers in VC++
void makeArray() {
int* m = NULL;
int n;
cout << "how many entries are there?"<<endl;
cin >> n;
m = new int[n];
int temp;
for (int x = 0; x < n; x++){
cout << "enter item:"<< x+1<< endl;
cin >> temp;
*(m + x) = temp;
}
for (int x = 0; x < n; x++){
cout << x+1 + ":" << "There is item: "<<*(m+x) << endl;
}
delete[]m;
}
int main() {
int x;
//makeArray();
appendNode(1);
appendNode(2);
appendNode(32);
appendNode(55);
appendNode(66);
insertNode(2, 0);
printLinkedList();
deleteNode(3);
printLinkedList();
sizeLinkedList();
}

c++ rehash on a LinkedList of pointers

I have a fully functioning hashMap class and everything seems to be working very well EXCEPT a rehash function designed to create a hashmap when the load factor of the previous hashmap reaches 0.8.
void HashMap::reHash()
{
logins = 0;
numberOfPairs = 0;
Node** newBucket = new Node* [(2 * lengthOfMap) + 1];
for(int i = 0; i < lengthOfMap; i++)
{
Node* oldHead = bucketList[i];
for(Node* temp = oldHead; temp != nullptr; temp = temp-> next)
{
std::string key = oldHead->key;
std::string value = oldHead->value;
unsigned int index = hash(key) % lengthOfMap;
if(newBucket[index] == nullptr)
{
std::cout << "HIT" << std::endl;
newBucket[i] = new Node;
newBucket[i]->key = key;
newBucket[i]->value = value;
newBucket[i]->next = nullptr;
numberOfPairs[index]++;
logins++;
}
else if (bucketList[index] != nullptr)
{
Node* temp = bucketList[index];
while(temp->next != nullptr)
{
temp = temp->next;
}
Node* n = new Node;
n->key = key;
n->value = value;
temp->next = n;
n->next = nullptr;
std::cout << "FAIL at index: " << index << std::endl;
//numberOfPairs[index]++;
logins++;
}
}
}
for(int i = 0; i < lengthOfMap; ++i)
{
if( bucketList[i] )
{
Node* first = bucketList[i];
while( first )
{
Node* temp = first->next;
delete first;
first = temp;
}
}
}
delete bucketList;
bucketList = newBucket;
lengthOfMap = (2 * lengthOfMap) + 1;
}
bucketList[] is my previous array full of Node* which each begin the first link in a linked list. I have added a couple std::cout for my own benefit, and I seem to be stuck in a permanent loop reading FAIL at index:0 over and over again. I will admit I am new to the for loop iterating through the linked list, which I think is the source of my problem, but I'm looking for any helpful input.
Thanks again.