Reverse of a Linked List using iteration - linked-list

Given a pointer to a linked list, I'm trying to reverse a linked using iteration(not recursive approach) in java. This is my code snippet.
Node reverse(Node head)
{
Node cur = head.next;
Node prev = head;
Node nxt;
while(cur!=null){
nxt = cur.next;
cur.next = prev;
prev = cur;
cur = nxt;
}
return prev;
}
But when I run it it gives error-"Time Limit Exceeded". So, there might be an infinite loop somewhere but I can't figure out where. Any help will be appreciated. Thank you.

You have not set next pointer of head node to null. firstnode.next is still pointing to the second node of given linkedlist which resulted in infinite looping.
Node cur = head.next;
Node prev = head;
prev.next = null; // add this

Related

mirror point in circular doubly linked list

I am supposed to count and list the mirror points in the circular doubly linked list. A particular element in the list is a mirror point if traversing the list in the clockwise direction from that element results in the same sequence of values as traversing the list from that element in the anticlockwise direction. All I can do is traverse in forward and backward direction.
void traversal(struct Node* start)
{
struct Node *temp = start;
printf("\nTraversal in forward direction \n");
while (temp->next != start)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("%d ", temp->data);
printf("\nTraversal in reverse direction \n");
Node *last = start->prev;
temp = last;
while (temp->prev != last)
{
printf("%d ", temp->data);
temp = temp->prev;
}
printf("%d ", temp->data);
}
any idea of how to solve the problem will be appreciated...
You have the ingredients. You should perform both traversals in tandem: use distinct pointers for these traversals, and move them at the same time:
bool traversal(struct Node* start)
{
struct Node *forward = start->next;
struct Node *backward = start->prev;
while (forward != start)
{
if (forward->data != backward->data) {
return false;
}
forward = forward->next;
backward = backward->prev;
}
return true;
}
This will return true when the given node is a mirror point. Remains for you to call this function for each node and count the number of times you get true as a return value...

Merge Sort for Singly Linked List seems to remove any numbers larger than the final number I input into the list

I am currently trying to formulate a mergeSort mechanism for a singly linked list. Through research and finding consistent ideas about A) a merge sort being the best way to sort a singly linked list, and B) that these are the key components for performing such an operation, I have arrived at this following code. It almost works exactly as intended, but will only return all of the integers larger than the last inputted number. For example, inputting 7, 6, 5, 4, 3, 2, 1 will return 1, 2, 3, 4, 5, 6, 7, but inputting 1, 2, 3, 4, 5 will only return 5. I've used random input orders so it's not a problem localised to just inputting the numbers in reverse order, but literally any order. If a number is smaller than the final number, it gets removed from the list in the sort process. I cannot locate the cause for this at all. My original problem was caused by an errant while loop that was stopping the iterations after one go, so once I removed that the merge sort was working, but for this problem I have just described.
Any and all advice or suggestions are more than welcome, and thanks for any input you have. My knowledge of linked lists and recursion isn't the greatest, so I really welcome all input/constructive criticism here.
public Node mergeSort(Node head) {
if (head == null || head.getNext() == null) return head;
Node midpoint = findMidpoint(head);
Node rightliststart = midpoint.getNext();
midpoint.setNext(null);
Node rightlist = mergeSort(rightliststart);
Node sorted = sort(leftlist, rightlist);
return sorted;
}
public Node findMidpoint(Node head) {
if (head == null) return head;
Node slowpointer = head;
Node fastpointer = slowpointer.getNext();
while (fastpointer != null) {
fastpointer = fastpointer.getNext();
if (fastpointer != null) {
slowpointer = slowpointer.getNext();
fastpointer = fastpointer.getNext();
}
}
return slowpointer;
}
public Node sort(Node one, Node two) {
Node temp = null;
if (one == null) return two;
if (two == null) return one;
if (one.getData() <= two.getData()) {
temp = one;
temp.setNext(sort(one.getNext(), two));
} else {
temp = two;
temp.setNext(sort(one, two.getNext()));
}
return temp;
}
Example merge code. This shows how the dummy node is used to simplify the code (avoids special case to update head on first node merged).
// merge two already sorted lists
static Node merge(Node list0, Node list1) {
if(list0 == null)
return list1;
if(list1 == null)
return list0;
Node temp = new Node(); // dummy node
Node dest = temp;
while(true){
if(list0.data <= list1.data){
dest.next = list0;
dest = list0;
list0 = list0.next;
if(list0 == null){
dest.next = list1;
break;
}
} else {
dest.next = list1;
dest = list1;
list1 = list1.next;
if(list1 == null){
dest.next = list0;
break;
}
}
}
return temp.next;
}
Example top down merge sort code. It scans the list one time to get the size of the list to avoid double scanning (fast, slow), only scanning n/2 nodes for each recursive split.
// return size of list
static int size(Node head) {
int i = 0;
while(head != null){
head = head.next;
i++;
}
return i;
}
// advance to node n
static Node advance(Node head, int n) {
while(0 < n--)
head = head.next;
return head;
}
// top down merge sort for single link list entry function
static Node sorttd(Node head) {
int n = size(head);
if(n < 2)
return head;
head = sorttdr(head, n);
return head;
}
// top down merge sort for single link list recursive function
static Node sorttdr(Node head, int n) {
if(n < 2)
return head;
int n2 = (n/2);
Node node = advance(head, n2-1);
Node next = node.next;
node.next = null;
head = sorttdr(head, n2);
next = sorttdr(next, n-n2);
head = merge(head, next);
return head;
}
Example bottom up merge sort code. It uses a small (32) array of lists, where array[i] is a list with 0 (empty slot) or 2^i nodes. array[{0 1 2 3 4 ...}] = sorted sub-lists with 0 or {1 2 4 8 16 ...} nodes. Nodes are merged into the array one at a time. A working list is created via a sequence of merge steps with a caller's list node and the leading non-empty slots in the array. The size of the working list doubles with each merge step. After each non-empty slot is used to merge into the working list, that slot is set to empty. After each sequence of merge steps is done, the first empty slot after the leading non-empty slots is set to the working list. A prior slots will now be empty. Once all nodes are merged into the array, the array is merged into a single sorted list. On a large list that doesn't fit in cache, and with randomly scattered nodes, there will be a lot of cache misses for each node accessed, in which case bottom up merge sort is about 30% faster than top down.
// bottom up merge sort for single link list
static Node sortbu(Node head) {
final int NUMLIST = 32;
Node[] alist = new Node[NUMLIST];
Node node;
Node next;
int i;
// if < 2 nodes, return
if(head == null || head.next == null)
return null;
node = head;
// merge node into array
while(node != null){
next = node.next;
node.next = null;
for(i = 0; (i < NUMLIST) && (alist[i] != null); i++){
node = merge(alist[i], node);
alist[i] = null;
}
if(i == NUMLIST) // don't go past end of array
i--;
alist[i] = node;
node = next;
}
// node == null
// merge array into single list
for(i = 0; i < NUMLIST; i++)
node = merge(alist[i], node);
return node;
}

How to delete all the nodes that less than value n in a link list?

How to delete all the nodes that less than value n in a link list? Anyone can show me a algorithm of how to do it? Thanks!
Assuming a Node type with a next and value field, and not sorted (pseudo code, pointers, references or whatever may be needed depending on the language)
first = deleteNodesLessThan(node, val)
first = node
curr = node
prev = node
while curr
# item to remove - delete it and update lins to maintain first,prev,curr
if curr.value < val
if tmp == first
first = curr.next
prev = first
else
prev.next = curr.next
end
delete(curr)
curr = prev.next
else
# nothing to remove, update to next
prev = curr
curr = curr.next
end
end
return first

Deleting a node from the middle of a link list, function prototype is: int particle_remove(struct particle* p);

I have been working on this for like 10 hours.
int particle_remove(struct particle* p);
How do I find the head when I'm passing the location of the "node-to-be-deleted" to the function?
I know that:
prev->next = curr->next;
free(curr);
how do I find the location of the head to traverse down to (curr -1)?
This is what I have so far:
int particle_remove(struct particle *p){
struct particle *curr = p;
struct particle *prev = *head; /* should point to the head */
if (p != NULL){
while (prev != curr){
prev=curr->next;
}
prev->next = curr->next;
free(curr);
}
return 0;
}
I have been over this a million times and I can't think of how to get to the head node, without passing a parameter of the location of the head node into the function. Is it possible to do this with the current function "signature" or do I have to add a reference to the head?
OK I have figured it out by creating a new function that takes both the current node to be destroyed and a pointer to the head, as I don't believe that just using a function to the node to be deleted will work as there is no reference to the head. (Unless someone can prove me wrong, please do!)
I ended up with a prototype that looks like this: (for those that are looking for a hint)
int particle_remove(struct particle *p, struct particle **head);
The problem is: you have to change the head pointer if the pointer to be deleted (p) happens to be first in the list. Using a pointer-to-pointer (a pointer to the head pointer) is the easiest way:
int particle_remove(struct particle *p){
struct particle **pp; /* should point to the head */
for(pp = &head; *pp; pp = &(*pp)->next){
if (*pp != p) continue;
*pp = p->next;
free(p);
break;
}
return 0;
}
If head is not a gobal pointer, you indeed end up with a function where the pointer to head is passed as an argument:
int particle_remove(struct particle **pphead, struct particle *p){
for( ; *pphead; pphead = &(*pphead)->next){
if (*pphead != p) continue;
*pphead = p->next;
free(p);
break;
}
return 0;
}
BTW: the return value is nonsense. If there is no useful return for the function, it could just as well return void.
OK, so the way to solve this using the original function prototype is if you use:
if(p->next != NULL){
/* do something */
}
You are checking to see if the next node is to be deleted. This gives you access to the previous node and the next node (to be deleted).

Sorted Insert in linked list

Given a problem to insert a new node within a sorted linked list in the correct position, I have come up with the following solution.
void SortedInsert(node** headref, node* newnode) {
node* prev = NULL;
node* curr = *headref;
for (; curr; ) {
if (curr->info > newnode->info) {
break;
}
prev = curr;
curr = curr->next;
}
if (!prev) {
newnode->next = *headref;
*headref = newnode;
} else {
newnode->next = prev->next;
prev->next = newnode;
}
}
Does this work.
Are there any edge cases this does not work for. Is there a simpler solution.
Instead of making curr point to the node before which you want to insert, make curr point to the pointer that points to the node before which you want to insert.

Resources