In the pseudo code below for reversing a linked list. How to read the first line in the while block? From what I've read about pseudo code, the arrow would be interpreted as saying 'next becomes equal to current'. If that is the case then why not just 'next = current'? Is there more information the arrow is providing that I'm missing?
while (current != None)
{
next = current -> next;
current -> next = prev;
prev = current;
current = next;
}
*head_ref = prev
Related
Given a singly linked list where each element contains a number and a pointer to the head of the list. Sum the first and last data and remove these nodes. Then sum the first and last data of the resulting linked list and remove these two nodes.
Keep doing this till the list becomes empty.
we have to find the maximum sum obtained from the resulting sum in O(1) space complexity.
The list is a singly linked list with even nodes.
My Thoughts:
One approach is to move the pointer to the last element at each iteration, remove the nodes, and keep a maxSum variable. This probably won't be an efficient solution.
If I understood correctly, a node in this linked list has two pointers: a pointer to the next node and one to the first node in the list.
There are several ways to solve this. Here is one:
Walk through the list and change the head pointer in each node to reference the previous node: this will give you a doubly linked list. Retain a pointer to the last node.
Now you can do a traversal in tandem starting at both ends of the list and walking towards each other.
Deleting nodes during that traversal is not really required. You could even restore the list to what it was originally in the second step.
It is even possible to do this without this extra head pointer in each node. In that case reverse the second half of the list.
Here is an implementation of the first idea, in JavaScript:
class Node {
constructor(data, head) {
this.data = data;
this.head = head || this; // default is node itself
this.next = null;
}
}
function createList(...values) {
if (!values) return null;
let head = new Node(values.shift()); // First value
let tail = head;
for (let value of values) { // Remaining values
tail.next = new Node(value, head);
tail = tail.next;
}
return tail.head;
}
function maxPairSum(head) {
if (!head) return -Infinity;
// Make doubly linked list, (ab)using node's head member
let tail;
for (tail = head; tail.next; tail = tail.next) {
tail.next.head = tail; // Next gets reference to previous
}
// Tandem walk, towards center
let maxSum = -Infinity;
for (let curr = head; curr != tail && curr != tail.next; curr = curr.next) {
maxSum = Math.max(maxSum, curr.data + tail.data);
tail = tail.head; // Is actually a reference to previous
}
// Restore head references (optional)
for (let curr = head; curr; curr = curr.next) {
curr.head = head;
}
return maxSum;
}
// Example run
let head = createList(2, 5, 1, 5, 4, 6);
let maxSum = maxPairSum(head);
console.log(maxSum); // 9
... And if you want to really remove the list, just clear the head reference. In JavaScript the garbage collector will free the unreachable memory; in some other languages (like C) you'll need to explicitly free the memory occupied by each node, before clearing the reference to the head node.
private static int max = 0, count = 0;
private static LinkedList top;
static int maximumPagesRec(LinkedList tail) {
if(tail.next==null)
max = max<top.data + tail.data ?top.data + tail.data: max;
else if(tail == top && count++ !=0){
max = max<top.data ?tail.data: max;
}
else if(top.next == tail && count++!=1)
max = max<top.data + tail.data ?top.data + tail.data: max;
else {
maximumPagesRec(tail.next);
}
top = top.next;
return max;
}
static int maximumPages(LinkedList head)
{ top = head;
return maximumPagesRec(head);
}
how about pushing all linked list value element to a stack, take 1->2->3->4 for example, and the stack will be 1234.
after that, we sum one by one and delete each linked list, store maximum value we got.
Hi can someone help me out which sorting algorithm used in this function
public void sortList() {
Node current = null, index = null;
int temp;
//Check whether list is empty
if(head == null) {
return;
}
else {
//Current will point to head
for(current = head; current.next != null; current = current.next) {
//Index will point to node next to current
for(index = current.next; index != null; index = index.next) {
//If current's data is greater than index's data, swap the data of current and index
if(current.data > index.data) {
temp = current.data;
current.data = index.data;
index.data = temp;
}
}
}
}
}
By the way it is Doubly Link List
The current node is fixed and then iteration is done from next node to the end(via index variable), at the end of one iteration of outer loop the node pointed to by current has correct value, then the current is progressed to next node.
This is Selection Sort, the most elementary sort
Fun fact : although slow because of complexity O(n^2) selection sort can be used when the write operation is expensive because it only swaps max n times for a list of size n
I have a linked list which is cyclic and I want to find out the total number of elements in this list. How to achieve this?
One solution that I can think of is maintaining two pointers. First pointer (*start) will always point to the starting node, say Node A.
The other pointer (*current) will be initialized as: current = start->next.
Now, just iterate each node with current -> next until it points to start.
And keep incrementing a counter: numberOfNodes++;
The code will look like:
public int countNumberOfItems(Node* start){
Node* current = start -> next;
int numberOfNodes = 1; //Atleast the starting node is there.
while(current->next != start){
numberOfNodes++;
current = current->next;
}
return numberOfNodes;
}
Let's say the list has x nodes before the loop and y nodes in the loop. Run the Floyd cycle detection counting the number of slow steps, s. Once you detect a meet point, run around the loop once more to get y.
Now, starting from the list head, make s - y steps, getting to the node N. Finally, run two slow pointers from N and M until they meet, for t steps. Convince yourself (or better prove) that they meet where the initial part of the list enters the loop.
Therefore, the initial part has s - y + t + 1 nodes, and the loop is formed by y nodes, giving s + t + 1 total.
You just want to count the nodes in your linked list right? I've put an example below. But in your case there is a cycle so you also need to detect that in order not to count some of the nodes multiple times.
I've corrected my answer there is now an ordinary count and count in loop (with a fast and slow pointer).
static int count( Node n)
{
int res = 1;
Node temp = n;
while (temp.next != n)
{
res++;
temp = temp.next;
}
return res;
}
static int countInLoop( Node list)
{
Node s_pointer = list, f_pointer = list;
while (s_pointer !=null && f_pointer!=null && f_pointer.next!=null)
{
s_pointer = s_pointer.next;
f_pointer = f_pointer.next.next;
if (s_pointer == f_pointer)
return count(s_pointer);
}
return 0;
}
First find the cycle using Floyd Cycle Detection algorithm and also maintain count when you checking cycle once found loop then print count for the same.
function LinkedList() {
let length = 0;
let head = null;
let Node = function(element) {
this.element = element;
this.next = null;
}
this.head = function() {
return head;
};
this.add = function(element) {
let node = new Node(element);
if(head === null){
head = node;
} else {
let currentNode = head;
while(currentNode.next) {
currentNode = currentNode.next;
}
currentNode.next = node;
}
};
this.detectLoopWithCount = function() {
head.next.next.next.next.next.next.next.next = head; // make cycle
let fastPtr = head;
let slowPtr = head;
let count = 0;
while(slowPtr && fastPtr && fastPtr.next) {
count++;
slowPtr = slowPtr.next;
fastPtr = fastPtr.next.next;
if (slowPtr == fastPtr) {
console.log("\n Bingo :-) Cycle found ..!! \n ");
console.log('Total no. of elements = ', count);
return;
}
}
}
}
let mylist = new LinkedList();
mylist.add('list1');
mylist.add('list2');
mylist.add('list3');
mylist.add('list4');
mylist.add('list5');
mylist.add('list6');
mylist.add('list7');
mylist.add('list8');
mylist.detectLoopWithCount();
There is a "slow" pointer which moves one node at a time. There is a "fast" pointer which moves twice as fast, two nodes at a time.
A visualization as slow and fast pointers move through linked list with 10 nodes:
1: |sf--------|
2: |-s-f------|
3: |--s--f----|
4: |---s---f--|
5: |----s----f|
At this point one of two things are true: 1) the linked list does not loop (checked with fast != null && fast.next != null) or 2) it does loop. Let's continue visualization assuming it does loop:
6: |-f----s---|
7: |---f---s--|
8: |-----f--s-|
9: |-------f-s|
10: s == f
If the linked list is not looped, the fast pointer finishes the race at O(n/2) time; we can remove the constant and call it O(n). If the linked list does loop, the slow pointer moves through the whole linked list and eventually equals the faster pointer at O(n) time.
given an IntegerIterator (which implements hasNext, next, remove),
implement a PositiveIterator that has hasNext, next, remove
Can anyone give some ideas for this problem? It's not a homework!
For example:
int[] a = new int[]{1,-2,-3,4,5,-6,7,-8,9};
IntegerIterator it = new IntegerIterator(a);
PositiveIterator iter = new PositiveIterator(it);
Console.WriteLine(iter.HasNext()); //true
Console.WriteLine(iter.HasNext()); //true
Console.WriteLine(iter.HasNext()); //true
Console.WriteLine(iter.Next()); //1
Console.WriteLine(iter.Next()); //4
Console.WriteLine(iter.Next()); //5
PositiveIterator.Next shouldn't be a problem. Just call Iterator.Next until the value is positive. PositiveIterator.Remove just needs a call to Iterator.Remove. PositiveIterator.HasNext is the reason why the code will be a bit ugly, since the given methods only allow unidirectional iteration.
class PositiveIterator:
int next = -1 //holds the next value to return
IntegerIterator iter //the integeriterator wrapped by this object
PositiveIterator(IntegerIterator it)
iter = it
//search for the first positive value for next
while iter.HasNext() AND ((next = iter.Next()) < 1)
NOOP
HasNext()
return next != -1
Next()
//the current value to return
int tmp = next
//search for the next positive value
while iter.HasNext() AND ((next = iter.Next()) < 1)
NOOP
if NOT iter.HasNext()
next = -1 //no next positive value available
return tmp
Remove()
if next == -1
return
iter.Remove()
//update the next value
next = Next()
Basically PositiveInteger needs to predict the value for the value that will be returned next.
This is pretty straight forward - override the constructor, HashNext() and Next() methods, such you will always have "in hand" the next positive value, while skipping all negative values.
Pseudo code:
class PositiveIterator:
private int next = -1;
private final Integer i;
PositiveIterator(Itertor i):
while (i.HashNext() && (next = i.Next()) <= 0) ;
//at this point next holds the next positive element, if such exists
this.i = i;
boolean HasNext():
return (next > 0)
int Next():
int tempVal = -1;
while (i.HashNext() && (tempVal = i.Next()) <= 0) ;
int res = next;
next = tempVal;
return next;
Note that at any point, in any method - next > 0 if and only if there is some positive element left in the array, and it will hold the next element you need t produce.
Here's my simple linked list program that creates a doubly linked list, and it works.
#include <iostream>
using namespace std;
typedef struct node {
int data;
node *next;
node *prev;
}node;
void printList(node *temp);
int main()
{
node *head;
head = new node;
head->prev = NULL;
node *next = head;
node *prev = head;
node *temp = head;
node *current = head;
//creates 100 nodes, last one points to next
for(int x = 0; x<100; x++)
{
temp->data = x;
current = temp;
temp = new node;
current->next = temp;
temp->prev = current;
temp->next = NULL;
}
//=========================================
printList(head);
//=========== set everything to head ===========
current = head;
prev = head;
//============= reverses linked list ============
while(current->next != NULL)
{
next = current->next; //moves next pointer to next node
current->prev = next; //points current's previous to next node
current = next; //set current pointer to next node
current->next = prev; //set current's next to previous node
prev = current; //move prev node up to current
}
//================================================
printList(head);
cout<<"done";
return 0;
}
void printList(node *temp)
{
while(temp->next != NULL)
{
cout<<temp->data<<'\n';
temp = temp->next;
}
}
Once I add the reverse function though, it hangs. Actually, the function itself works, but in an IDE, when I LOOP it, it prints out all the values, then just hangs(sits there with blinking cursor) and does nothing.
Solution: Got it to work. This is what my function ended up being.
current = head; //set current pointer to head
prev = head; //set previous pointer to head
next = current->next; //moves next pointer to next node
current->next = NULL; //set the next of the header to NULL, because it will actually be the last
//node of reversed list.
current->prev = next; //set previous of the header to the next node.
while(next != NULL)
{
current = next;
next = current->next;
current->prev = next;
current->next = prev;
prev = current;
}
Your reverse algorithm is basically broken.
On the first pass through:
current = head; // Current is pointing at node 0, node0->next is 1 from before
prev = head; // Prev is pointing at node 0
next = current->next; // next is pointing at 1
current->prev = next; // node0->prev is pointing at 1
current = next; // current is pointing at 1
current->next = prev // node1->next is pointing at 0
then next pass
next = current->next // read up there ^^^ node1->next is pointing at 0
... so next goes back to to node 0.
That is not what you meant to do - it causes you to loop around nodes 1 and zero repeatedly, instead of progressing to node 2 and beyond...
Note that you could have easily debugged this if you put this code into the reverse loop:
cout<<"\nStarting iteration"
cout<<"\nNext is at" << next->data
cout<<"\nCurrent is at" << current->data
cout<<"\nCurrent->next is" << current->next->data
etc... doesn't take long to type, reveals all :)
(probably you would cut it down to do 3 instead of 100)
I just did the steps for 3 nodes manually (on paper) to deduce this answer...
Look this simple solution..
Node* Reverse(Node* head)
{
Node * curr=head;
Node * prev=NULL,* nxt=NULL;
while(curr!=NULL)
{
nxt=curr->next;
curr->next=prev;
curr->prev=nxt;
prev=curr;
curr=nxt;
}
return prev;
// Complete this function
// Do not write the main method.
}