Reverse the pointers in a linked list - c

Hello guys could you please help me in writing a procedure to reverse the pointers in a linked list . for example A->B->C->D would become A<-B<-C<-D without using extra linked list .
Edit:
------ okay guys so i have been looking for solution for this problem here is the code in case u want it :
void reverse_list(){
struct node *next, *current,*previous;
previous = NULL;
current =head;
while(current != NULL){
next = current->next;
current->next = previous;
previous=current;
current = next;
}
head = previous;
}

You could think of the list as a stack. Then you could easily reverse such a list by "popping" the nodes and "pushing" them into a new list.
The above could be done both destructively (destroying the old list) and non-destructively (creating the new list as a reversed copy of the original list).

As you didn't mention if you are implementing the linked list yourself or not.
So firstly I am assuming that you are doing it by yourself. So following is an implementation of linked list and again its pointers are reversed to make the link list reverse. You can take an idea from it.
#include<stdio.h>
#include<stdlib.h>//for using malloc
struct Node//Defining a structure for linked list's node
{
int info;//assuming it is an integer linked list
struct Node *link;//this pointer links a node to it's immediate neighbor node
};
struct Node *head=NULL,*temp;//some initializations and declarations
void insertion(int data)//To insert elements to linked list
{
struct Node *ptr;
ptr=malloc(sizeof(*ptr));//creating a new node for the newcomer
ptr->info=data;//taking the given integer value for the node to hold
//initializing with null as the current node may be the last node and
//if it is then it will point nobody
//...but if it is not when a new node comes in the future it will eventually be
//replaced to point the newcomer
ptr->link=NULL;
if(head==NULL)//head still null means we are creating the first node
{ //handling the head separately as it has no parent node
head=ptr;
temp=ptr;//copying the current node's pointer to temp such that we can
//find it as a parent of next node
}
else//for the rest of the nodes' creation
{
//as temp is the pointer to the previous node, so previous node is linking
//to its next node, i.e, the current node
temp->link=ptr;
//updating the temp to point the current node such that it can act as a parent node
//when the next node comes
temp=ptr;
}
}
void reversePointers()
{
struct Node *trav,*from=NULL,*temp;
for(trav=head;;)
{
if(trav->link==NULL)//if we have reached to the end
{
head=trav;//then the reverse linked list's head should point to the last element
trav->link=from;//and making the second last node as it's next node
break;
}
temp=trav;//saving current node pointer to update the "from" pointer
trav=trav->link;//advancing current node pointer to forward
temp->link=from;//making the current node to point to it's previous node
from=temp;//saving current node's pointer which will be used in next iteration
}
}
void traverse()//to traverse the nodes
{
struct Node *ptr=head;
while(ptr!=NULL)
{
printf("%d ",ptr->info);
ptr=ptr->link;
}
printf("\n");
}
int main(void)
{
int i,n,t;
printf("Enter Number of elements: ");
scanf("%d",&n);
printf("Enter Elements: ");
for(i=0;i<n;i++)
{
scanf("%d",&t);
insertion(t);
}
printf("Before reversing the pointers the elements are: ");
traverse();
//let's reverse the pointers to make the list to go backward
reversePointers();
printf("After reversing the pointers the elements are: ");
traverse();
}
Secondly if you are using STL list then the approach is quite straightforward. Just use,
your_list_name.reverse()
Again if you want to reverse the STL list just for iteration purpose then there is no need to actually reverse it. Instead you can use reverse iterator as following (say for an integer list):
for(list<int>::reverse_iterator it=your_list_name.rbegin();it!=your_list_name.rend();it++)
{
//do whatever you want
}

Related

Is there a way in C to create new nodes in a linked list without memory allocation?

I just learned the concept of a linked list in C, and tried implementing it. What I did was create a pointer head, and a pointer itr. To create a new node I would initialize a node normally (without using pointers), and then attach a pointer to it.
struct node temp; //A single node contains a value 'num' and a pointer to the next node.
temp.num=x;
temp.next=NULL;
if(head==NULL){
head=&temp;
}
else{
itr=head;
while(itr->next!=NULL){
itr=itr->next;
}
itr->next=&temp;
}
This method is not working, and based on my limited knowledge of pointers in C, I cannot figure out why. I know that the right way to do it is by using malloc to create new nodes, but I need to know why this method does not work.
Full Program:
#include <stdio.h>
struct node{
int num;
struct node *next;
};
int main(){
struct node *head=NULL;
struct node *itr;
struct node temp;
int choice;
printf("1. Enter new Node, 2. Traverse all nodes, 3. Exit.");
int x;
while(1){
printf("\nEnter your choice: ");
scanf("%d", &choice);
if(choice==1){
printf("Enter value: ");
scanf("%d", &x);
temp.num=x;
temp.next=NULL;
if(head==NULL){
head=&temp;
}
else{
itr=head;
while(itr->next!=NULL){
itr=itr->next;
}
itr->next=&temp;
}
}
else if(choice==2){
if(head==NULL){
printf("Empty List");
continue;
}
printf("The values are: ");
itr=head;
printf("%d ", itr->num);
while(itr->next!=NULL){
itr=itr->next;
printf("%d ", itr->num);
}
}
else{
break;
}
}
}
A linked list generally consists of several nodes, in which each node points to the next node in the list. The last node in the linked list should point to NULL to mark the end of the list.
However, you have only allocated memory for a single node. Therefore, you will only be able to store a single node in the linked list.
The code for adding the first node to the linked list is correct. However, the code for adding a second node cannot work, because you have not allocated any memory for the second node.
What your code for adding the second node is actually doing is overwriting the first node, and making this first node point to itself. That is why you are getting an infinite loop, if you attempt to print the linked list afterwards.
Therefore, I suggest that you instead use malloc for allocating memory for the nodes. That way, you won't be limited to a single node.
You must show your whole code.
I guess , in your case, if you define a function like this, the temp elem is funciton local variable, you need use malloc to make it accessable out of the function.
int addNode(struct node *head, inx x) {
struct node temp; //A single node contains a value 'num' and a pointer to the next node.
temp.num=x;
temp.next=NULL;
if(head==NULL){
head=&temp;
}
else{
itr=head;
while(itr->next!=NULL){
itr=itr->next;
}
itr->next=&temp;
}
}

Sentinel Node in a C Linked List

I'm trying to learn more about linked lists in C and I recently stumbled upon the Sentinel Node concept, but I can't wrap my head around it. According to the slides I have, the sentinel node should be the first thing on the list when it's created and the last when other nodes are added. There should be a pointer to permanently point to the Sentinel Node.
All those stuff confuse me and I would love some help with the implementation.
/*this is a simple LL implementation*/
#include <stdio.h>
#include <stdlib.h>
struct List
{
int data;
struct List *next;
};
void ListInsert(int new_data)
{
struct List *p;
p = (struct List *)malloc(sizeof(struct List));
p->data = new_data;
p->next = (head);
head = p;
}
void printList(struct List *q)
{
q = head;
while (q != NULL)
{
printf("%d ", q->data);
q = q->next;
}
printf("\n");
}
int main()
{
ListInsert(5);
ListInsert(7);
ListInsert(6);
ListInsert(4);
ListInsert(2);
printList(head);
return 0;
}
Now, if I want to create the sentinel node, how should I proceed?
According to the slides i have, the sentinel node should be the first
thing on the list when its created and the last when other nodes are
added.There should be a pointer to permanently point to the Sentinel
Node.
Let's start with the most important point: the purpose of a sentinel node, which is to mark the end of the list. There will not be real data associated with a sentinel node, so a list containing only a sentinel node is logically empty.
A few things follow from that, including:
the identity of the sentinel node is a property of the whole list, not of any (other) particular node
list manipulation algorithms need to be written differently for linked lists whose ends are marked by a sentinel than for those whose ends are marked by some other means.
each list need a place to store the sentinel's identity
a list that is expected to have a sentinel is invalid if it does not have one
There are many ways to implement the details, all with their own advantages and disadvantages.
Personally, I would be inclined (in the non-sentinel case, too) to have a structure to represent an overall list, separate from the structure used to represent a list node. A pointer to the list's head node would be a member of this structure, and in the sentinel-terminated-list case, so would be a pointer to the sentinel node. When you create a new list, you create a sentinel node for it, too; initially, the list's head and sentinel pointers will both point to that node. The head pointer may be changed, but the sentinel pointer must not be. When you append to the list, the appended node gets placed just before the sentinel. It is an error to try to delete the sentinel from the list.
It is to your advantage to write the code for this yourself.
Create it. You said "There should be a pointer to permanently point to the Sentinel Node", so create the pointer. Then use the pointer as the terminator of the list instead of NULL.
Sentinel node - Wikipedia
/*this is a simple LL implementation*/
#include <stdio.h>
#include <stdlib.h>
struct List
{
int data;
struct List *next;
};
struct List sentinel_node_instance;
/* a pointer to permanently point to the Sentinel Node */
struct List* const SENTINEL_NODE = &sentinel_node_instance;
/* the sentinel node should be the first thing on the list when it's created */
struct List* head = SENTINEL_NODE;
void ListInsert(int new_data)
{
struct List *p;
p = (struct List *)malloc(sizeof(struct List));
p->data = new_data;
p->next = (head);
head = p;
}
void printList(void)
{
struct List* q = head;
while (q != SENTINEL_NODE)
{
printf("%d ", q->data);
q = q->next;
}
printf("\n");
}
int main()
{
ListInsert(5);
ListInsert(7);
ListInsert(6);
ListInsert(4);
ListInsert(2);
printList();
return 0;
}
Another variation of a sentinel node is for a circular doubly linked list, where it is both a head node and a sentinel node. Visual Studio implements std::list in this manner.
head.next = pointer to first node or to head if empty list
head.prev = pointer to last node or to head if empty list
first.prev = pointer to head node
last.next = pointer to head node

Difference between linked list traversal **while(thead != NULL)** and while(thead->next !=NULL)

Can anyone tell me what is the difference between while(thead != NULL) and while(thead->next !=NULL) because for traversing the list thead != NULL is not working while thead->next works.
According to my understanding head node is just a pointer to the starting node and not the the starting node itself.
See this if u have doubt.Here head just stores address.
//thead means temp head variable to store the address head points to.
This is the code for insertion.
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void insert(int x)
{
struct node *temp=(struct node *)malloc(sizeof(struct node));
temp->data=x;
temp->next=NULL;
if(head==NULL)
{
head=temp;
}
else
{
struct node * thead;
thead=head;
while(thead->next!=NULL)
{
thead=thead->next;
}
thead->next=temp;
}
}
void print()
{
struct node *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
temp=temp->next;
}
}
int main()
{
head=NULL;
int i,n,x;
printf("enter number of nodes");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter no");
scanf("%d",&x);
insert(x);
}
print();
}
If we replace thead ->next != NULL by thead !=NULL then dev c++ stops working.Vice versa happens in the printf for traversal ...
So can someone answer the difference between the above two?
Also,Is head node the first node which contains both data and address or does it just stores addresses like in the diagram above?
Also if the head node is only a pointer which stores address then how are we able access thead->next ?
And when is a pointer to a structure NULL?
Thanks
Now since I have actually understood....for those who are still stuck I am writing this....
When I use (thead!=NULL) the thead pointer actually points to each and every element in the list.When it reaches the last element,it still traverses to the next element which is NULL unlike (thead->next!=NULL) which stops at the last element of the linked list.
In case of print we need to print all the values in the list so we use while(thead!=NULL) as we need to print the last element too.For traversing we simply need to make the pointer point towards the last node so we can stop at it and not traverse till we reach the NULL pointer.
We cant dereference NULL and so there was an error.
With print(), code does not need to remember the last node address after the loop
temp=head;
while(temp!=NULL) {
printf("%d",temp->data);
temp=temp->next;
}
// temp == NULL at this point and code does not care what the last node was.
With insert(), code does need to remember the last node address after the loop.
// First handle special case where the head of the list is NULL
// otherwise ....
while(thead->next!=NULL) {
thead = thead->next;
}
// temp->next == NULL at this point
// Code can use `thead` to access the last node's members.
thead->next = temp;
Is head node the first node which contains both data and address or does it just stores addresses like in the diagram above?
struct node *head is a pointer. When head != NULL, it pointer the the frist node which contains data and a next pointer.
if the head node is only a pointer which stores address then how are we able access thead->next ?
thead is initialized with head. By de-referencing thead, code has access to that node's members including .next.
when is a pointer to a structure NULL?
Question is unclear. A pointer to a struct is NULL when it has a value equal to NULL. This is usually as the end in the linked-list code employs.

What more does the code need to delete a node from a linked list successfully?

I want to delete a given node from a linked list by the node's index number (serial number). So what I tried to do in my function is that, first I have taken the user input of the index number. Then I used two node type pointers temp and current. I started traversing the list with current and when the index number of the node matches with the user input, I tried to delete the node. So far it is correct. I am facing problem with the deletion logic. Here is the code I tried:
void delete_node(struct node **start,int index_no)
{
int counter=0;
struct node *temp, *current;
temp=(struct node *)malloc(sizeof(struct node));
current=(struct node *)malloc(sizeof(struct node));
current=*start;
while(current->next!=NULL)
{
counter++;
if(counter==index_no)
{
temp= current->next;
free(current);
/*I guess some code is missing here. Help me finding the logic.*/
}
else
{
printf("\n The index number is invalid!!");
}
}
}
The commented portion lacks the deletion logic.
Also, I have a feeling that this code is not space and time-efficient. If it is so, please suggest to a way to make it more compact.
Why are you allocating two nodes in the delete function, then leaking their memory? It seems they should be initialized to start or one of its successors.
You also need to update the next pointer in the previous element and potentially also the start (head) of the list if the removed element was the first (ie. index_no == 1).
You also have an off-by-one error where the final node can never be deleted, because only a node with a ->next pointer will be considered for deletion.
Suggested reading: A Tutorial on Pointers and Arrays in C.
Deleting from a linked list is actually:
find the pointer that points to us
(if found) make it point to our .next pointer instead
delete our node.
In order to change the pointer that points to us, we need a pointer to it: a pointer to pointer. Luckily the first argument already is a pointer to pointer, it presumably points to the head pointer that points to the first list item.
struct node
{
struct node *next;
int num;
} ;
void delete(struct node **pp, int num) {
struct node *del;
int counter;
for (counter=0; *pp; pp= &(*pp)->next) {
if(counter++ == num) break;
}
if (!*pp) { printf("Couldn't find the node(%d)\n", num); return; }
/* if we get here, *pp points to the pointer that points to our current node */
del = *pp;
*pp = del->next;
free(del);
}

Deleting a middle node from a single linked list when pointer to the previous node is not available

Is it possible to delete a middle node in the single linked list when the only information available we have is the pointer to the node to be deleted and not the pointer to the previous node?After deletion the previous node should point to the node next to deleted node.
It's definitely more a quiz rather than a real problem. However, if we are allowed to make some assumption, it can be solved in O(1) time. To do it, the strictures the list points to must be copyable. The algorithm is as the following:
We have a list looking like: ... -> Node(i-1) -> Node(i) -> Node(i+1) -> ... and we need to delete Node(i).
Copy data (not pointer, the data itself) from Node(i+1) to Node(i), the list will look like: ... -> Node(i-1) -> Node(i+1) -> Node(i+1) -> ...
Copy the NEXT of second Node(i+1) into a temporary variable.
Now Delete the second Node(i+1), it doesn't require pointer to the previous node.
Pseudocode:
void delete_node(Node* pNode)
{
pNode->Data = pNode->Next->Data; // Assume that SData::operator=(SData&) exists.
Node* pTemp = pNode->Next->Next;
delete(pNode->Next);
pNode->Next = pTemp;
}
Mike.
Let's assume a list with the structure
A -> B -> C -> D
If you only had a pointer to B and wanted to delete it, you could do something like
tempList = B->next;
*B = *tempList;
free(tempList);
The list would then look like
A -> B -> D
but B would hold the old contents of C, effectively deleting what was in B. This won't work if some other piece of code is holding a pointer to C. It also won't work if you were trying to delete node D. If you want to do this kind of operation, you'll need to build the list with a dummy tail node that's not really used so you guarantee that no useful node will have a NULL next pointer. This also works better for lists where the amount of data stored in a node is small. A structure like
struct List { struct List *next; MyData *data; };
would be OK, but one where it's
struct HeavyList { struct HeavyList *next; char data[8192]; };
would be a bit burdensome.
Not possible.
There are hacks to mimic the deletion.
But none of then will actually delete the node the pointer is pointing to.
The popular solution of deleting the following node and copying its contents to the actual node to be deleted has side-effects if you have external pointers pointing to nodes in the list, in which case an external pointer pointing to the following node will become dangling.
I appreciate the ingenuity of this solution (deleting the next node), but it does not answer the problem's question. If this is the actual solution, the correct question should be "delete from the linked list the VALUE contained in a node on which the pointer is given". But of course, the correct question gives you a hint on solution.
The problem as it is formulated, is intended to confuse the person (which in fact has happened to me, especially because the interviewer did not even mention that the node is in the middle).
One approach would be to insert a null for the data. Whenever you traverse the list, you keep track of the previous node. If you find null data, you fix up the list, and go to the next node.
The best approach is still to copy the data of the next node into the node to be deleted, set the next pointer of the node to the next node's next pointer, and delete the next node.
The issues of external pointers pointing to the node to be deleted, while true, would also hold for the next node. Consider the following linked lists:
A->B->C->D->E->F and G->H->I->D->E->F
In case you have to delete node C (in the first linked list), by the approach mentioned, you will delete node D after copying the contents to node C. This will result in the following lists:
A->B->D->E->F and G->H->I->dangling pointer.
In case you delete the NODE C completely, the resulting lists will be:
A->B->D->E->F and G->H->I->D->E->F.
However, if you are to delete the node D, and you use the earlier approach, the issue of external pointers is still there.
The initial suggestion was to transform:
a -> b -> c
to:
a ->, c
If you keep the information around, say, a map from address of node to address of the next node then you can fix the chain the next time to traverse the list. If need to delete multiple items before the next traversal then you need to keep track of the order of deletes (i.e. a change list).
The standard solution is consider other data structures like a skip list.
Maybe do a soft delete? (i.e., set a "deleted" flag on the node) You can clean up the list later if you need to.
Not if you want to maintain the traversability of the list. You need to update the previous node to link to the next one.
How'd you end up in this situation, anyway? What are you trying to do that makes you ask this question?
You'll have to march down the list to find the previous node. That will make deleting in general O(n**2). If you are the only code doing deletes, you may do better in practice by caching the previous node, and starting your search there, but whether this helps depends on the pattern of deletes.
Given
A -> B -> C -> D
and a pointer to, say, item B, you would delete it by
1. free any memory belonging to members of B
2. copy the contents of C into B (this includes its "next" pointer)
3. delete the entire item C
Of course, you'll have to be careful about edge cases, such as working on lists of one item.
Now where there was B, you have C and the storage that used to be C is freed.
Considering below linked list
1 -> 2 -> 3 -> NULL
Pointer to node 2 is given say "ptr".
We can have pseudo-code which looks something like this:
struct node* temp = ptr->next;
ptr->data = temp->data;
ptr->next = temp->next;
free(temp);
yes, but you can't delink it. If you don't care about corrupting memory, go ahead ;-)
Yes, but your list will be broken after you remove it.
In this specific case, traverse the list again and get that pointer! In general, if you are asking this question, there probably exists a bug in what you are doing.
In order to get to the previous list item, you would need to traverse the list from the beginning until you find an entry with a next pointer that points to your current item. Then you'd have a pointer to each of the items that you'd have to modify to remove the current item from the list - simply set previous->next to current->next then delete current.
edit: Kimbo beat me to it by less than a minute!
You could do delayed delinking where you set nodes to be delinked out of the list with a flag and then delete them on the next proper traversal. Nodes set to be delinked would need to be properly handled by the code that crawls the list.
I suppose you could also just traverse the list again from the beginning until you find the thing that points to your item in the list. Hardly optimal, but at least a much better idea than delayed delinking.
In general, you should know the pointer to the item you just came from and you should be passing that around.
(Edit: Ick, with the time it took me to type out a fullish answer three gazillion people covered almost all the points I was going to mention. :()
The only sensible way to do this is to traverse the list with a couple of pointers until the leading one finds the node to be deleted, then update the next field using the trailing pointer.
If you want to delete random items from a list efficiently, it needs to be doubly linked. If you want take items from the head of the list and add them at the tail, however, you don't need to doubly link the whole list. Singly link the list but make the next field of the last item on the list point to the first item on the list. Then make the list "head" point to the tail item (not the head). It is then easy to add to the tail of the list or remove from the head.
You have the head of the list, right? You just traverse it.
Let's say that your list is pointed to by "head" and the node to delete it "del".
C style pseudo-code (dots would be -> in C):
prev = head
next = prev.link
while(next != null)
{
if(next == del)
{
prev.link = next.link;
free(del);
del = null;
return 0;
}
prev = next;
next = next.link;
}
return 1;
The following code will create a LL, n then ask the user to give the pointer to the node to be deleted. it will the print the list after deletion
It does the same thing as is done by copying the node after the node to be deleted, over the node to be deleted and then delete the next node of the node to be deleted.
i.e
a-b-c-d
copy c to b and free c so that result is
a-c-d
struct node
{
int data;
struct node *link;
};
void populate(struct node **,int);
void delete(struct node **);
void printlist(struct node **);
void populate(struct node **n,int num)
{
struct node *temp,*t;
if(*n==NULL)
{
t=*n;
t=malloc(sizeof(struct node));
t->data=num;
t->link=NULL;
*n=t;
}
else
{
t=*n;
temp=malloc(sizeof(struct node));
while(t->link!=NULL)
t=t->link;
temp->data=num;
temp->link=NULL;
t->link=temp;
}
}
void printlist(struct node **n)
{
struct node *t;
t=*n;
if(t==NULL)
printf("\nEmpty list");
while(t!=NULL)
{
printf("\n%d",t->data);
printf("\t%u address=",t);
t=t->link;
}
}
void delete(struct node **n)
{
struct node *temp,*t;
temp=*n;
temp->data=temp->link->data;
t=temp->link;
temp->link=temp->link->link;
free(t);
}
int main()
{
struct node *ty,*todelete;
ty=NULL;
populate(&ty,1);
populate(&ty,2);
populate(&ty,13);
populate(&ty,14);
populate(&ty,12);
populate(&ty,19);
printf("\nlist b4 delete\n");
printlist(&ty);
printf("\nEnter node pointer to delete the node====");
scanf("%u",&todelete);
delete(&todelete);
printf("\nlist after delete\n");
printlist(&ty);
return 0;
}
void delself(list *list)
{
/*if we got a pointer to itself how to remove it...*/
int n;
printf("Enter the num:");
scanf("%d",&n);
while(list->next!=NULL)
{
if(list->number==n) /*now pointer in node itself*/
{
list->number=list->next->number; /*copy all(name,rollnum,mark..)
data of next to current, disconnect its next*/
list->next=list->next->next;
}
list=list->next;
}
}
If you have a linked list A -> B -> C -> D and a pointer to node B. If you have to delete this node you can copy the contents of node C into B, node D into C and delete D. But we cannot delete the node as such in case of a singly linked list since if we do so, node A will also be lost. Though we can backtrack to A in case of doubly linked list.
Am I right?
void delself(list *list)
{
/*if we got a pointer to itself how to remove it...*/
int n;
printf("Enter the num:");
scanf("%d",&n);
while(list->next!=NULL)
{
if(list->number==n) /*now pointer in node itself*/
{
list->number=list->next->number;
/*copy all(name,rollnum,mark..) data of next to current, disconect its next*/
list->next=list->next->next;
}
list=list->next;
}
}
This is a piece of code I put together that does what the OP was asking for, and can even delete the last element in the list (not in the most elegant way, but it gets it done). Wrote it while learning how to use linked lists. Hope it helps.
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <string>
using namespace std;
struct node
{
int nodeID;
node *next;
};
void printList(node* p_nodeList, int removeID);
void removeNode(node* p_nodeList, int nodeID);
void removeLastNode(node* p_nodeList, int nodeID ,node* p_lastNode);
node* addNewNode(node* p_nodeList, int id)
{
node* p_node = new node;
p_node->nodeID = id;
p_node->next = p_nodeList;
return p_node;
}
int main()
{
node* p_nodeList = NULL;
int nodeID = 1;
int removeID;
int listLength;
cout << "Pick a list length: ";
cin >> listLength;
for (int i = 0; i < listLength; i++)
{
p_nodeList = addNewNode(p_nodeList, nodeID);
nodeID++;
}
cout << "Pick a node from 1 to " << listLength << " to remove: ";
cin >> removeID;
while (removeID <= 0 || removeID > listLength)
{
if (removeID == 0)
{
return 0;
}
cout << "Please pick a number from 1 to " << listLength << ": ";
cin >> removeID;
}
removeNode(p_nodeList, removeID);
printList(p_nodeList, removeID);
}
void printList(node* p_nodeList, int removeID)
{
node* p_currentNode = p_nodeList;
if (p_currentNode != NULL)
{
p_currentNode = p_currentNode->next;
printList(p_currentNode, removeID);
if (removeID != 1)
{
if (p_nodeList->nodeID != 1)
{
cout << ", ";
}
cout << p_nodeList->nodeID;
}
else
{
if (p_nodeList->nodeID !=2)
{
cout << ", ";
}
cout << p_nodeList->nodeID;
}
}
}
void removeNode(node* p_nodeList, int nodeID)
{
node* p_currentNode = p_nodeList;
if (p_currentNode->nodeID == nodeID)
{
if(p_currentNode->next != NULL)
{
p_currentNode->nodeID = p_currentNode->next->nodeID;
node* p_temp = p_currentNode->next->next;
delete(p_currentNode->next);
p_currentNode->next = p_temp;
}
else
{
delete(p_currentNode);
}
}
else if(p_currentNode->next->next == NULL)
{
removeLastNode(p_currentNode->next, nodeID, p_currentNode);
}
else
{
removeNode(p_currentNode->next, nodeID);
}
}
void removeLastNode(node* p_nodeList, int nodeID ,node* p_lastNode)
{
node* p_currentNode = p_nodeList;
p_lastNode->next = NULL;
delete (p_currentNode);
}
Void deleteMidddle(Node* head)
{
Node* slow_ptr = head;
Node* fast_ptr = head;
Node* tmp = head;
while(slow_ptr->next != NULL && fast_ptr->next != NULL)
{
tmp = slow_ptr;
slow_ptr = slow_ptr->next;
fast_ptr = fast_ptr->next->next;
}
tmp->next = slow_ptr->next;
free(slow_ptr);
enter code here
}

Resources