Adding a node to the end of a linked list - c++

I've been trying to add an item to the end of a linked list. I think I have a handle on the concept but i'm having difficulty implementing the code. In particular, being able to traverse a linked list and find the tail. Here is what i have so far. I've been at this for a while trying different things. Any help would be appreciated.
##include <iostream>
using namespace std;
class node
{
public:
int data;
node *next;
};
class linkedList
{
private:
node* ptrHead;
node* ptrTail;
int size;
public:
linkedList(); //default constructor
void display();
void addFront(int);
void removeFront();
void addBack(int);
void removeBack();
};
//default constructor
linkedList::linkedList(){
size = 0;
ptrHead = ptrTail = NULL;
}
//display linked list
void linkedList::display(){
node* current = ptrHead;
while (current != NULL) {
cout << current->data << " "; //display current item
current = current->next; //move to next item
}
cout << size;
}
//add item to front of linked list
void linkedList::addFront(int addData){
node* n = new node;
n->next = ptrHead;
n->data = addData;
ptrHead = n;
size++;
}
//remove item from front of linked list
void linkedList::removeFront(){
node* n = ptrHead;
ptrHead = ptrHead->next;
delete n;
size--;
}
void linkedList::addBack(int addData){ ////work in progress
node* n = new node; //create new node
n->data = addData; //input data
n->next = NULL; //set node to point to NULL
if ( ptrTail == NULL ) // or if ( ptrTail == nullptr )
{
ptrHead = n;
ptrTail = n;
}
else
{
ptrTail->next = n;
ptrTail = n;
}
size++;
}
//this is the test code from my main function
int main()
{
//test code
linkedList list;
list.addFront(40);
list.addFront(30);
list.addFront(20);
list.addFront(10);
list.addFront(0);
list.addBack(50);
list.addBack(60);
list.display(); //50 60 7 (the 7 is the count/size of the linked list)
cout << endl;
}

for(int i=1; i<size; i++)
pCurrent = pCurrent->next;
pCurrent = n;
This will work. But you have to keep the size variable as real size of the Linked List.
Or If you want to add element in the end always, you can follows the below steps.
Keep a extra node tail and add the element to that.
if(head == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
tail = tail->next;
}

You did not show the definition of your linkedList.
So I can only suppose that it has data members ptrTail and ptrHead. In this case the function will look the following way
void linkedList::addBack(int addData)
{
node* n = new node; //create new node
n->data = addData; //input data
n->next = NULL; //set node to point to NULL
if ( ptrTail == NULL ) // or if ( ptrTail == nullptr )
{
ptrHead = n;
}
else
{
ptrTail->next = n;
}
ptrTail = n;
size++;
}
Function addFront can be defined the similar way
void linkedList::addFront(int addData)
{
node* n = new node; //create new node
n->data = addData; //input data
if ( ptrHead == NULL ) // or if ( ptrHead == nullptr )
{
ptrTail = n;
}
n->next = ptrHead;
ptrHead = n;
size++;
}
One more function
void linkedList::removeFront()
{
if ( ptrHead != NULL )
{
if ( ptrTail == ptrHead ) ptrTail = NULL;
node* n = ptrHead;
ptrHead = ptrHead->next;
delete n;
size--;
}
}

Try this
node* pCurrent = ptrHead;
if( pCurrent != NULL ){
//find tail
while (pCurrent->next != NULL)
pCurrent = pCurrent->next;
// add new node at end of tail
pCurrent->next = n;
} else {
pCurrent = n;
}
}

Related

C++ Inserting into a linked list

I am writing a program that modifies a linked list. The problem I am having is when inserting nodes into the linked list. The first few nodes are inserted and moved properly, but when reaching the end of the linked list some nodes are either removed or not displayed.
Function for inserting
void LinkedList::insert(int num, int pos)
{
Node *temp1 = new Node;
temp1->data = num;
temp1->next = NULL;
if(pos == 0)
{
temp1->next = head;
head = temp1;
return;
}
Node *temp2 = head;
for(int i = 0; i < pos-1; i++)
{
temp2 = temp2->next;
}
temp1->next = temp2->next;
temp2->next = temp1;
}
Node structure
struct Node
{
int data;
Node *next;
};
int size;
Node *head, *tail;
Driver code
nums.insert(1, 0); // 1 in location 0
nums.insert(5, 4); // 5 in location 4
nums.insert(3, 7); // 3 in location 7
List before insert
8 6 7 8 0 9
List after insert
1 8 6 7 5 8
Expected after insert
1 8 6 7 5 8 0 9 3
Would the values excluded from being display needed to be stored and inserted afterwards? Or is the inserting itself not being coded properly/missing elements?
Thanks for your help.
Full code
#include "linkedlist.h"
LinkedList::LinkedList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LinkedList::~LinkedList()
{
if(head != nullptr)
{
Node *temp;
while(head != nullptr)
{
temp = head->next;
// deletes head
delete head;
// goes to next element
head = temp;
}
}
}
void LinkedList::display()
{
Node *temp = head;
for(int i = 0; i < size; i++)
{
cout << temp->data << "\t";
temp = temp->next;
}
cout << endl;
}
void LinkedList::append(int num)
{
// list is empty
if(head == nullptr)
{
head = new Node;
head->data = num;
head->next = nullptr;
// sets tail to head
tail = head;
}
else
{
// creates new node
Node *temp = new Node;
// sets new node data
temp->data = num;
temp->next = nullptr;
// sets previous tail link to new node
tail->next = temp;
// sets this node to new tail
tail = temp;
}
// increments size
size++;
}
void LinkedList::pop()
{
if(size > 1)
{
Node *temp = head;
// loops to node before tail
while(temp->next->next != nullptr)
{
temp = temp->next;
}
// deletes tail
delete tail;
// sets new tail
tail = temp;
tail->next = nullptr;
}
// if there's only one item
else if(size == 1)
{
Node *temp = tail;
// head and tail are now null
head = nullptr;
tail = nullptr;
// deletes node
delete temp;
}
size--;
}
int LinkedList::min()
{
int min = head->data;
struct Node *temp = head;
while(temp != nullptr)
{
if(min > temp->data)
{
min = temp->data;
}
temp = temp->next;
}
return min;
}
int LinkedList::max()
{
int max = head->data;
struct Node *temp = head;
while(temp != nullptr)
{
if(max < temp->data)
{
max = temp->data;
}
temp = temp->next;
}
return max;
}
int LinkedList::mean()
{
int sum = 0;
int average = 0;
struct Node *temp = head;
while(temp != nullptr)
{
sum += temp->data;
temp = temp->next;
}
average = sum / size;
return average;
}
void LinkedList::sort()
{
Node *current1 = head;
Node *current2 = head;
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size - 1; j++)
{
if(current1->data < current2->data)
{
int temp = current1->data;
current1->data = current2->data;
current2->data = temp;
}
current2 = current2->next;
}
current2 = head;
current1 = head->next;
for(int p = 0; p < i; p++)
{
current1 = current1->next;
}
}
}
void LinkedList::reverse()
{
Node *current1 = head;
Node *current2 = head;
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size - 1; j++)
{
if(current1->data > current2->data)
{
int temp = current1->data;
current1->data = current2->data;
current2->data = temp;
}
current2 = current2->next;
}
current2 = head;
current1 = head->next;
for(int p = 0; p < i; p++)
{
current1 = current1->next;
}
}
}
int LinkedList::linearSearch(int key)
{
Node *search = nullptr;
Node *temp = head;
Node *current = head;
int count = 0;
while(current != NULL && current->data != key)
{
count++;
temp = current;
current = current->next;
}
if(current != NULL)
{
search = current;
current = current->next;
}
key = count;
return key;
}
void LinkedList::insert(int num, int pos)
{
Node *temp1 = new Node;
temp1->data = num;
temp1->next = NULL;
if(pos == 0)
{
temp1->next = head;
head = temp1;
return;
}
Node *temp2 = head;
for(int i = 0; i < pos-1; i++)
{
temp2 = temp2->next;
}
temp1->next = temp2->next;
temp2->next = temp1;
}
You have a size member that your display function uses, but you never increment it in insert. So while the element gets added, you don't increase the size of the list.
Reading your whole code and getting to the solution may consume lot of time but if you want i have a code ready which is properly working. If you wanted to use this. Please go for it and also, please feel free to ask my anything though this link
#include <iostream>
using namespace std;
struct node
{
int data;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int n)
{
node *tmp = new node;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
static void display(node *head)
{
if(head == NULL)
{
cout << "NULL" << endl;
}
else
{
cout << head->data << endl;
display(head->next);
}
}
static void concatenate(node *a,node *b)
{
if( a != NULL && b!= NULL )
{
if (a->next == NULL)
a->next = b;
else
concatenate(a->next,b);
}
else
{
cout << "Either a or b is NULL\n";
}
}
};
int main()
{
linked_list a;
a.add_node(1);
a.add_node(2);
linked_list b;
b.add_node(3);
b.add_node(4);
linked_list::concatenate(a.gethead(),b.gethead());
linked_list::display(a.gethead());
return 0;
}

Why is my print function not working? Linked list

I am doing a class assignment, where I have to create a linked list representing a big number, but I cant get the print function to work.
This is the code:
Header
class List
{
private:
struct node
{
int data;
node* next;
};
node* head;
node* temp;
node* curr;
public:
List();
void addNode(std::string digits);
void printList();
};
Constructor
List::List()
{
head = NULL;
curr = NULL;
temp = NULL;
}
Function that creates the list
void List::addNode(string digits)
{
int o = 1;
int j = 0;
int i = 0;
node *n;
node *head;
node *temp;
//=================================================================================//
n = new node;
if (digits[0]=='-')
{
n -> data = -1;
head = n;
temp = n;
}
else
{
n -> data = 1;
head = n;
temp = n;
}
//================================================================================//
if ((head->data) == -1)
{
while (o < digits.length())
{
n = new node;
n->data = stoi(digits.substr(o,1));
temp -> next = n;
temp = temp -> next;
o++;
}
}
else
{
while(i < digits.length())
{
n = new node;
n->data = stoi(digits.substr(i,1));
temp -> next = n;
temp = temp -> next;
i++;
}
}
The print function I've been trying to implement, it gives no output (blank):
void List::printList()
{
node* curr = head;
while(curr != NULL)
{
cout<<curr -> data<<" ";
curr = curr -> next;
}
}
The list prints fine when I use this code in the addNode function:
if ((head -> data) == -1)
{
while(j < digits.length())
{
cout<<head -> data<<" ";
head = head -> next;
j++;
}
}
else
{
while(j<=digits.length())
{
cout<<head -> data<<" ";
head = head -> next;
j++;
}
}
For starters these data members
node* temp;
node* curr;
are redundant. Instead of them you can use similar local variables in member functions of the class if it is required.
The function addNode deals with the local variable head instead of the data member with the same name.
void List::addNode(string digits)
{
int o = 1;
int j = 0;
int i = 0;
node *n;
node *head;
//…
Also you forgot to set the data member next of the last node to nullptr.
If the member function will be called a second time then there will be memory leaks.
Calling the standard function std::stoi for one character
n->data = stoi(digits.substr(i,1));
is inefficient.
The class can look the following way as it is shown in the demonstrative program below. You will need to add other required member functions (as for example the copy constructor or destructor) yourself.
#include <iostream>
#include <string>
class List
{
private:
struct node
{
int data;
node *next;
} *head = nullptr;
public:
List() = default;
void addNode( const std::string &digits );
std::ostream & printList( std::ostream &os = std::cout ) const;
};
void List::addNode( const std::string &digits )
{
if ( !digits.empty() &&
!( digits.size() == 1 && ( digits[0] == '-' || digits[0] == '+') ) )
{
node **current = &head;
while ( *current )
{
node *tmp = *current;
*current = ( *current )->next;
delete tmp;
}
std::string::size_type i = 0;
*current = new node { digits[i] == '-' ? -1 : 1, nullptr };
if ( digits[i] == '-' || digits[i] == '+' ) ++i;
for ( ; i < digits.size(); i++ )
{
current = &( *current )->next;
*current = new node { digits[i] - '0', nullptr };
}
}
}
std::ostream & List::printList( std::ostream &os ) const
{
if ( head != nullptr )
{
if ( head->data == -1 ) os << '-';
for ( node *current = head->next; current != nullptr; current = current->next )
{
os << current->data;
}
}
return os;
}
int main()
{
List lst;
lst.addNode( "-123456789" );
lst.printList() << '\n';
lst.addNode( "987654321" );
lst.printList() << '\n';
return 0;
}
The program output is
-123456789
987654321

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;

Merge Sort Singly Linked List in C++ failing for large input

Update. its working for 65,519 in the FOR LOOP. If i increase it to 65,520, it fails. Completely strange.
This program is not working for large inputs. It is perfect for small inputs. I am getting an exception on Xcode.
Thread 1 : EXC_BAD_ACCESS (code=2, address = 0x7fff5f3fffb8).
Kindly let me know how I can bypass this strange error.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct Node * nodePtr;
struct Node{
int data;
nodePtr next;
};
nodePtr globalHead;
void partition(nodePtr head, nodePtr *front, nodePtr *back){
nodePtr fast;
nodePtr slow;
if (head == NULL || head->next == NULL){
*front = head; // &a
*back = NULL; // &b
}else{
slow = head;
fast = head->next;
while(fast != NULL){
fast = fast->next;
if(fast != NULL){
slow = slow->next;
fast = fast->next;
}
}
*front = head; // a
*back = slow->next; // b
slow->next = NULL;
//printList(*front);
//printList(*back);
}
}
nodePtr mergeLists(nodePtr a, nodePtr b){
nodePtr mergedList = NULL;
if (a == NULL){
return b;
}else if (b == NULL){
return a;
}
try {
if (a->data <= b->data){
mergedList = a;
mergedList->next = mergeLists(a->next, b);
}else{
mergedList = b;
mergedList->next = mergeLists(a, b->next);
}
}
catch (int e) {
cout << "Error is . . " << e << endl;
}
return mergedList;
}
void mergeSort(nodePtr *source){
nodePtr head = *source;
nodePtr a = NULL;
nodePtr b = NULL;
if(head == NULL || head->next == NULL){
return;
}
partition(head, &a, &b);
mergeSort(&a);
mergeSort(&b);
*source = mergeLists(a, b);
}
void push(nodePtr *head, int data){
nodePtr newNode = (nodePtr) malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
if ((*head) == NULL){
*head = newNode;
globalHead = *head;
}else{
(*head)->next = newNode;
*head = newNode;
}
}
void printList(nodePtr head){
nodePtr current = head;
while(current != NULL){
printf("%d ",current->data);
current = current->next;
}
printf("\n");
}
// *head = head in the main function,
// it is only there to connect the two and
// not let make the function return anything
// passed by reference
// globalHead points to the start of the linked list
// if you are passing the address over here you have to
// make a double pointer over there in the function
int main(void)
{
nodePtr head = NULL;
// linked list is formed from top to bottom fashion
// push is done in constant time O(1)
long long int i;
//Pushing 200,000 Elements to the Linked List.
for(i=1 ; i<=200000 ; i++) {
push(&head, rand()%200000);
}
printList(globalHead);
mergeSort(&globalHead);
cout << "After Sorting . . \n";
printList(globalHead);
return 0;
}
Using recursion mergeLists() is the issue, it will call itself for every node on the list. Try changing the code so that the code loops and appends nodes to the initially empty mergeList, using a second pointer to node, or optionally a pointer to pointer to node which is initially set to &mergeList. For example, using the name pMerge instead of mergeList:
Node * mergeLists(Node *a, Node *b)
{
Node *pMerge = NULL; // ptr to merged list
Node **ppMerge = &pMerge; // ptr to pMerge or prev->next
if(a == NULL)
return b;
if(b == NULL)
return a;
while(1){
if(a->data <= b->data){ // if a <= b
*ppMerge = a;
a = *(ppMerge = &(a->next));
if(a == NULL){
*ppMerge = b;
break;
}
} else { // b <= a
*ppMerge = b;
b = *(ppMerge = &(b->next));
if(b == NULL){
*ppMerge = a;
break;
}
}
}
return pMerge;
}
Here is example code of a fast method to sort a linked list using an array of pointers to lists aList[], where aList[i] points to a list of size 2 to the power i, that makes use of mergeLists().
#define NUMLISTS 32 // size of aList
Node * mergeSort(NODE *pList)
{
Node * aList[NUMLISTS]; // array of pointers to lists
Node * pNode;
Node * pNext;
int i;
if(pList == NULL) // check for empty list
return NULL;
for(i = 0; i < NUMLISTS; i++) // zero array
aList[i] = NULL;
pNode = pList; // merge nodes into array
while(pNode != NULL){
pNext = pNode->next;
pNode->next = NULL;
for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
pNode = mergeLists(aList[i], pNode);
aList[i] = NULL;
}
if(i == NUMLISTS)
i--;
aList[i] = pNode;
pNode = pNext;
}
pNode = NULL; // merge array into one list
for(i = 0; i < NUMLISTS; i++)
pNode = mergeLists(aList[i], pNode);
return pNode;
}

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();
}