Given a linked list how do i crush all more than two nodes which are continuous and have same value.
eg
1->3->3->3->5->4->4->4->5->5->2->5
step1 crush 3
1->5->4->4->4->5->5->2->5
step2 crush 4
1->5->5->5->2->5
step3 crush 5
return 1->2->5
I tried below code but its returning 1->5->->5->2->5
public void Crush()
{
Node prev = null, current = head;
if (head == null)
{
return;
}
prev = current;
while (current.next != null)
{
int k = 0;
while (current != null && current.next != null && current.data == current.next.data)
{
k++;
current = current.next;
}
if (k < 2)
{
// prev.next = current;
current = current.next;
}
else
{
prev.next = current.next;
current = current.next;
}
}
head = prev;
}
1->3->3->3->5->4->4->4->5->5->2->5
^
1->5->5->5->2->5
^
When you remove the run of 4s, it creates a new run of 5s. However, the first 5 has already been skipped over, so only 2 5s are counted.
Anytime a run is removed, you'll need to reprocess the list from the beginning.
Related
I'm trying to create an interval binary tree. It is similar to a regular binary search tree, but nodes are disjoint intervals rather than single numbers. If an interval being inserted has common elements with the already existing intervals, then these intervals are combined into one, and the union of them is inserted. I hope the example below will make it easier to understand.
Here is the program I have created: https://onecompiler.com/c/3ymwk8zv2
The main part is:
struct node *delete(struct node* root, int key)
{
if(root == NULL) return root;
if(key < root->low)
root->left = delete(root->left, key);
else if(key > root->low)
root->right = delete(root->right, key);
else {
if(root->left == NULL)
return root->right;
else if(root->right == NULL)
return root->left;
struct node *min = minValue(root->right);
root->low = min->low;
root->high = min->high;
root->id = min->id;
root->right = delete(root->right, root->low);
}
return root;
}
int insertIntersect(struct node *root, int low, int high, int *left, int *right)
{
if(root == NULL)
return 0;
insertIntersect(root->left, low, high, left, right);
insertIntersect(root->right, low, high, left, right);
if(!intersect(root->low, root->high, low, high))
return 0;
else
{
*left = min(*left,min(root->low, low));
*right = max(*right, max(root->high, high));
root->inter = 1;
delete(root, root->low);
}
return 0;
}
struct node *insert(struct node *root, int low, int high)
{
if(root == NULL)
return createNode(low, high);
if(low < root->low && high < root->high)
root->left = insert(root->left, low, high);
else if (low > root->low && high > root->high)
root->right = insert(root->right, low, high);
else
{
int left = INT_MAX, right = INT_MIN;
insertIntersect(root, low, high, &left, &right);
root->low = left;
root->high = right;
}
return root;
}
Executing my code for the above example produces a tree with the following nodes:
(1-3)
(8-9)
(4-25)
even though (8-9) should be incorporated into the (4-25) interval.
I'm looking for help with debugging my solution. I will also appreciate ideas for improving my code.
To be honest, the solution turned out to be way more complex than I thought initially. There are many things to fix in your code, so I decided to write it from scratch. It's hard to describe everything precisely, so apart from the description, I added code snippets with an implementation in C.
Let each node has the following properties:
interval - with a and b defining its ends
left - the left subtree's root
right - the right subtree's root
First, we have to define the delete operation as it'll be used when inserting an interval. When deleting we must take into account the fact existing tree nodes can be removed or divided into two parts. It's a bit complex as there are six cases to consider:
root->interval.a < interval.a and interval.b < root->interval.b - interval is within root->interval. root should be split into two nodes with only left and only right child correspondingly. One of these parts is chosen as the new root and the other becomes its second child.
interval.a < root->interval.a - interval contains values lower than the ones in root. It makes sense to delete interval from the left subtree. If all values in interval are lower, there is nothing more to do.
root->interval.b < interval.b - interval contains values higher than the one in root. It makes sense to delete interval from the right subtree. If all values in interval are higher, there is nothing more to do.
interval.a < root->interval.a and root->interval.b < interval.b - root->interval is within interval. root should be deleted. Both children's subtrees are in their final state as previously if needed interval was deleted from them. One of the children becomes the new root and the second one is inserted into its subtree.
interval.b is within root->interval - After handling the above cases interval.a <= root->interval.a, so the left part of root->interval is removed by adjusting root->interval.a.
interval.a is within root->interval - After handling the above cases root->interval.b <= interval.b, so the right part of root->interval is removed by adjusting root->interval.b.
Node *delete(Node *root, Interval interval) {
if (root == NULL) {
return NULL;
}
if (root->interval.a < interval.a && interval.b < root->interval.b) {
// arbitrary choice of the right part as the new root
Interval leftRootInterval = { .a = root->interval.a, .b = interval.a };
Node *leftRoot = createNode(leftRootInterval);
leftRoot->left = root->left;
root->interval.a = interval.b;
root->left = leftRoot;
return root;
}
if (interval.a < root->interval.a) {
root->left = delete(root->left, interval);
if (interval.b <= root->interval.a) {
return root;
}
}
if (root->interval.b < interval.b) {
root->right = delete(root->right, interval);
if (root->interval.b <= interval.a) {
return root;
}
}
if (interval.a < root->interval.a && root->interval.b < interval.b) {
Node *leftRoot = root->left;
Node *rightRoot = root->right;
free(root);
// arbitrary choice of leftRoot as the new root
if (leftRoot != NULL) {
root = leftRoot;
while (leftRoot->right != NULL) {
leftRoot = leftRoot->right;
}
leftRoot->right = rightRoot;
return root;
}
// there is only the right root
return rightRoot;
}
if (root->interval.a < interval.b && interval.b < root->interval.b) {
root->interval.a = interval.b;
return root;
}
// root->interval.a < interval.a && interval.a < root->interval.b
root->interval.b = interval.a;
return root;
}
Note the comments in the code above saying the new root is selected arbitrarily. Any of the two nodes could be chosen. Selecting always the same node in those places may lead to unbalance in the tree depending on the sequence of operations. One option to mitigate this issue is to make the choice randomly.
When interval is inserted there are four cases to analyze:
interval.b < root->interval.a - interval's values are lower than root->interval's ones. Insert it to the left subtree.
root->interval.b < interval.a - interval's values are higher than root->interval's ones. Insert it into the right subtree.
interval.a < root->interval.a - Because of previously checked case 1 root->interval.a <= interval.b - root->interval should be extended to the left. Note that some nodes from the left subtree can be absorbed by root->interval after the extension. Delete interval from the left subtree to remove them. Then check if the remaining part of root->left->interval should be also combined with root->interval.
root->interval.b < interval.b - Because of previously checked case 2 interval.a <= root->interval.b - root->interval should be extended to the right. Note that some nodes from the right subtree can be absorbed by root->interval after the extension. Delete interval from the right subtree to remove them. Then check if the remaining part of root->right->interval should be also combined with root->interval.
Node *insert(Node *root, Interval interval) {
if (root == NULL) {
return createNode(interval);
}
if (interval.b < root->interval.a) {
root->left = insert(root->left, interval);
return root;
}
if (root->interval.b < interval.a) {
root->right = insert(root->right, interval);
return root;
}
if (interval.a < root->interval.a) {
root->interval.a = interval.a;
root->left = delete(root->left, interval);
Node *leftRoot = root->left;
if (leftRoot != NULL && root->interval.a == leftRoot->interval.b) {
root->interval.a = leftRoot->interval.a;
root->left = leftRoot->left;
free(leftRoot);
}
}
if (root->interval.b < interval.b) {
root->interval.b = interval.b;
root->right = delete(root->right, interval);
Node *rightRoot = root->right;
if (rightRoot != NULL && root->interval.b == rightRoot->interval.a) {
root->interval.b = rightRoot->interval.b;
root->right = rightRoot->right;
free(rightRoot);
}
}
return root;
}
Note that cases 3 and 4 aren't mutually exclusive. root->interval can be extended in both directions. Only one end, however, has to be adjusted at a time as the second one if needed is adjusted when handling the other case.
I am trying to write code for deleting a node from a doubly linked list, but something is going wrong. I can't seem to delete the first node, while any node from the middle or end node is being deleted. Also, my head and the tail pointer are not being updated after deleting the respective node positions.
code -
class Node{
public:
int data;
Node* prev;
Node* next;
//constructor
Node(int d) {
this -> data = d;
this -> prev = NULL;
this -> next = NULL;
}
// destructor
~Node() {
int val = this -> data;
if(next != NULL) {
delete next;
next = NULL;
}
cout << "memory free for node with data " << val << endl;
}
};
void deleteNode(int position, Node* head) {
//deleting the first node
if(position == 1) {
Node* temp = head;
temp -> next -> prev = NULL;
head = temp -> next;
temp -> next = NULL;
delete temp;
} else {
// deleteing middle or last node
Node* curr = head;
Node* prev = NULL;
int cnt = 1;
while(cnt < position) {
prev = curr;
curr = curr -> next;
cnt++;
}
curr -> prev = NULL;
prev -> next = curr -> next;
curr -> next = NULL;
delete curr;
}
}
int main() {
Node* head = NULL;
Node* tail = NULL;
insertAtHead(head, tail, 11);
insertAtHead(head, tail, 18);
insertAtHead(head, tail, 9);
print(head);
insertAtTail(head, tail, 21);
insertAtPosition(head, tail, 2, 34);
print(head);
deleteNode(1, head);
cout << "head - " << head -> data << endl;
cout << "tail - " << tail -> data << endl;
print(head);
A few issues:
deleteNode might delete the tail node, and so may need to adapt the value of tail. This never happens. tail should be an argument.
deleteNode currently has code that modifies head, but this will only affect the local variable with that name, not the caller's variable. So this parameter should be call-by-reference: &head. Same for the missing &tail parameter.
There are unsafe references, like temp -> next -> prev, when temp -> next could be nullptr.
In the else case there is code missing to set curr->next->prev = prev
Assuming that the provided position is a valid one, the code could be corrected to this:
void deleteNode(int position, Node* &head, Node* &tail) {
//deleting the first node
if(position == 1) {
Node* temp = head;
if (temp -> next != nullptr) {
temp -> next -> prev = nullptr;
} else {
tail = nullptr;
}
head = temp -> next;
temp -> next = nullptr;
delete temp;
} else {
// deleteing middle or last node
Node* curr = head;
Node* prev = nullptr;
int cnt = 1;
while(cnt < position) {
prev = curr;
curr = curr -> next;
cnt++;
}
prev -> next = curr -> next;
if (curr->next != nullptr) {
curr->next->prev = prev;
} else {
tail = prev;
}
prev -> next = curr -> next;
curr -> prev = NULL;
curr -> next = NULL;
delete curr;
}
}
Suppose you have two linked list 5->4 ( 4 5 ) and 5->4->3 ( 3 4 5) you have to return a resultant linked list 0->9->3 (3 9 0).
/*struct Node
{
int data;
Node* next;
}; */
Node* addTwoLists(Node* first, Node* second){
int sum = 0, carry = 0;
Node *three, *temp, *prev;
three = new Node;
temp = three;
while(first!=NULL || second!=NULL) {
sum = carry + (first?first->data:0+second?second->data:0);
carry = sum/10;
temp->data = sum;
temp->next = new Node;
prev = temp;
temp = temp->next;
first = first->next;
second = second->next;
}
if(carry > 0) {
temp->data = carry;
temp->next = NULL;
}
else {
delete temp;
prev->next = NULL;
}
return three;
}
I am getting Run Time Error(Code Dumped) for the above code.
I am trying to solve this algorithmic problem based on linked list data structure. The question is as follows:
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
My solution to the problem is:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode partition(ListNode head, int x) {
if(head == null) return null;
ListNode headNode = new ListNode(-1);
headNode.next = head;
ListNode tail = head;
while(tail.next!=null){
tail = tail.next;
}
ListNode actualTail = tail;
ListNode current = headNode;
while(current!=actualTail && current.next!=actualTail){
if(current.next.val >= x && current.next!=tail){
System.out.println("Moving "+current.next.val+" to end of list, ahead of "+tail.val);
ListNode temp = current.next;
current.next = current.next.next;
tail.next = temp;
tail = tail.next;
tail.next = null;
}else{
current = current.next;
}
}
return headNode.next;
}
}
While some test cases work fine with this code such as the one mentioned above, there are a set of test cases that fail, in that I am unable to maintain the original relative ordering of the nodes in the list.
For example:
list = [1->2]
x = 0
My result:
[2,1]
Expected:
[1,2]
Any help would be greatly appreciated.
I think you can do it in a simpler way:
Keep 2 lists, one for lower nodes and other for greater nodes.
Iterate the list adding the nodes to the corresponding list.
Concatenate the lower list with greater list
Something like this:
public ListNode Partition(ListNode head, int x)
{
ListNode lowerHead = null, lowerTail = null; //Head and Tail of lower list
ListNode greaterHead = null, greaterTail = null; //Head and Tail of greater list
ListNode current = head;
while (current != null)
{
if (current.val < x)
{
if (lowerHead == null) lowerHead = current; //If is the first node in the list
if (lowerTail == null) lowerTail = current; //set the head an tail to the same value
else lowerTail = lowerTail.next = current; //Otherwise, add the node and update the tail
}
else
{
if (greaterHead == null) greaterHead = current; //If is the first node in the list
if (greaterTail == null) greaterTail = current; //set the head an tail to the same value
else greaterTail = greaterTail.next = current; //Otherwise, add the node and update the tail
}
current = current.next;
}
if (greaterHead != null)
greaterTail.next = null;
if (lowerHead == null) return greaterHead;
else
{
lowerTail.next = greaterHead;
return lowerHead;
}
}
Order is preserved since nodes are added as they appear in the original list
It can be done in place, in O(N) time O(1) space. Just keep
track of the immediate preceding node, before the first node, that is
greater than or equal to the X.
This node acts as the boundary between the nodes that are less than X
and nodes that are greater than or equal to X.
Refer the code along with inline comments.
class Solution {
public ListNode partition(ListNode head, int x) {
// Assume that list has at least one instance of X and x = 3
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode prev = dummy;
ListNode curr = head;
// Keeps track of the preceding node, before the first value greater than or equal to x.
ListNode large = null;
// Tracks weather the first node greater than or equal to x has been found.
boolean isFirstLargeFound = false;
while(curr != null) {
if (curr.val >= x) {
if (!isFirstLargeFound) {
large = prev;
isFirstLargeFound = true;
}
} else if (isFirstLargeFound) {
// If the current value is less than x and the first larger value has
// been found, we need to swap the nodes.
//
// Consider the example: 1->4->0->3->2->5, the curr node is at value 0.
// At this point of time the first larger value i.e. 4 has been already
// found, hence we have to move the Node with value 0 to a place before
// the node with value 4.
//
// Before: 1->4->0->3->2->5
// After: 1->0->4->3->2->5
ListNode temp = large.next;
prev.next = curr.next;
large.next = curr;
// Ensures that the first element that is >=X, is always next of large node.
curr.next = temp;
large = large.next;
}
prev = curr;
curr = curr.next;
}
return dummy.next;
}
}
I solved it in Python and works fine.
current = runner = ll.head
while runner:
if runner.value < part:
temp = current.value
current.value = runner.value
runner.value = temp
current = current.next
runner = runner.next
else:
runner = runner.next
Even though this is an bit old thread, I hope this will be useful for someone.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def insert_node(self, val):
new_node = ListNode(val)
if self.head is None:
self.head = self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
if head is None or head.next is None:
return head
else:
tmp = head
low = LinkedList()
high = LinkedList()
while tmp is not None:
if tmp.val < x:
low.insert_node(tmp.val)
else:
high.insert_node(tmp.val)
tmp = tmp.next
if low.head is not None:
tail = low.head
while tail.next is not None:
tail = tail.next
tail.next = high.head
output = low.head
else:
output = high.head
return output
Given a linked list of numbers. Swap every 2 adjacent links. For example, if a linked list given to you is:
a->b->c->d->e->f
Output expected:
b->a->d->c->f->e
Every 2 alternate links have to be swapped.
I have written a solution here. Can you suggest me some other solution. Can you comment on my solution and help me better write it?
void SwapAdjacentNodes (Node head)
{
if (head == null) return;
if (head.next == null) return;
Node curr = head;
Node next = curr.Next;
Node temp = next.Next;
while (true)
{
temp = next.Next;
next.Next = curr;
curr.Next = temp;
if (curr.Next != null)
curr = curr.Next;
else
break;
if (curr.Next.Next!=null)
next = curr.Next.Next;
else
break;
}
}
Take a look at this C++ solution:
public void exchangeAdjElements(){
LLMain backup=current.next;
LLMain temp = current.next;
LLMain previous=current;
while(current!=null && current.next!=null){
previous.next=current.next;
current.next=temp.next;
temp.next=current;
if(current.next!=null){
previous=current;
current=current.next;
temp=current.next;
}
}
current=backup;
}
Here current is the head node.
Here's a rough sketch of a much simpler version, assuming Node has "Next" and "Data" members:
for (Node n = head; n && n.Next; n = n.Next.Next) {
void* tmp = n.Data;
n.Data = n.Next.Data;
n.Next.Data = tmp;
}
In other words, stop at every other node in the list and swap its data with the next one (the one). Simple.
Edit: Above solution swaps data within the nodes but not the nodes themselves. If you want to swap actual nodes, the solution requires more logic.
#dkamins: U are changing the values but in these type of questions, interviewers generally ask for pointer shuffling.
My attempt for the problem:
void swap (struct list **list1)
{
struct list *cur, *tmp, *next;
cur = *list1;
if(!cur || !cur->next)
return;
*list1 = cur->next;
while(cur && cur->next)
{
next = cur->next;
cur->next = next->next;
tmp = cur->next;
next->next = cur;
if(tmp && tmp->next)
cur->next = cur->next->next;
cur = tmp;
}
}
Here it is in complete runnable Java. This is purely pointer play.
public class ListSwap {
// the swap algorithm
static void swap(Node current) {
while (true) {
Node next1 = current.next;
if (next1 == null) break;
Node next2 = next1.next;
if (next2 == null) break;
Node next3 = next2.next;
current.next = next2;
next2.next = next1;
next1.next = next3;
current = next1;
}
}
// the rest is infrastructure for testing
static class Node {
Node next;
final char data; // final! Only pointer play allowed!
Node(char data, Node next) {
this.data = data;
this.next = next;
}
#Override public String toString() {
return data + (next != null ? next.toString() : "");
}
}
(continued...)
static class List {
Node head;
List(String data) {
head = null;
String dataReversed = new StringBuilder(data).reverse().toString();
for (char ch : dataReversed.toCharArray()) {
head = new Node(ch, head);
}
head = new Node('#', head);
}
#Override public String toString() {
return head.toString();
}
void swapPairs() {
swap(head);
}
}
public static void main(String[] args) {
String data = "a1b2c3d4e5";
for (int L = 0; L <= data.length(); L++) {
List list = new List(data.substring(0, L));
System.out.println(list);
list.swapPairs();
System.out.println(list);
}
}
}
(see full output)
I adapted #dkamins' solution, in a way. Instead of taking in a pointer to a pointer, I return the new head. I also beefed it up.
struct Node
{
struct Node *next;
int data;
};
typedef struct Node * NodePtr;
NodePtr swapEveryTwo(NodePtr head)
{
NodePtr newHead = (head && head->next) ? head->next : head;
NodePtr n = head;
while(n && n->next)
{
NodePtr tmp = n; // save (1)
n = n->next; // (1) = (2)
tmp->next = n->next; // point to the 3rd item
n->next = tmp; // (2) = saved (1)
n = tmp->next; // move to item 3
// important if there will be further swaps
if(n && n->next) tmp->next = n->next;
}
// return the new head
return newHead;
}
Basically, the new head of the list is either the current head if NULL or length 1, or the 2nd element.
In the swap loop, tmp will eventually become the 2nd element, but initially it is the first. We need it therefore to point to the 3rd element, which is the purpose of tmp->next = n->next;. I don't use a for loop because if we did, it is less intuitive - the reevaluation expression would only appear to be jumping by 1 node per iteration. At the end of the while loop, n = tmp->next; makes intuitive sense - we are pointing it to the element after tmp, the 2nd element.
The most important part is the last line. Because we are doing this in a forward direction, we have to remember that the previous iteration's 2nd element is almost certainly going to be pointing to the current iteration's eventual 4th element, because this iteration will swap 3 and 4. So at the end of the iteration, if we realize we are going to swap again next iteration, we quietly point the 2nd element to the current 4th element, knowing that next iteration it will be the 3rd element and all is right in the world.
For example, if the list is 2 -> 7 -> 3 -> 5:
n = 2
tmp = 2
n = 7
tmp->next = 3 (2 -> 3)
n->next = 2 (7 -> 2)
n = 3
7 -> 2 -> 3 -> 5
but then there will be swaps, so the last statement says
7 -> 2 -> 5 3?
This is ok because n = 3, so we haven't lost that node. Next iteration:
n = 3
tmp = 3
n = 5
tmp->next = NULL (3 -> NULL)
n->next = 3 (5 -> 3)
n = NULL
Leading to the final 7 -> 2 -> 5 -> 3 answer.
I guess to make it more efficient, it would be better to take another argument n in the function.
This n is used for count , i.e after how much count the nodes needs to be changed. in above case n= 2.
And then keep on iterating until you hit the n and used the reverse linklist alog or recursive reverse linklist algo to do it.
void ReverseLinkList(struct node* head, int n)
{
if( head == null || null <= 0)
return;
struct node* start = head;
struct node* next = null;
struct node* end = head;
int count = 1;
while(end->next != null)
{
if(count == n)
{
next = end->next;
count = 1;
//Use ReverseLinklist From start to end
end->next = next;
end = next;
start = next;
}
else
{
end = end->next;
count++;
}
}
}
void SwapAdjacentNodes (Node head)
{
if (head == null) return;
if (head.next == null) return;
Node curr = head;
Node next = curr.Next;
Node temp = next.Next;
while (true)
{
temp = next.Next;
next.Next = curr;
curr.Next = temp;
if (curr.Next != null)
curr = curr.Next;
else
break;
if (curr.Next.Next!=null)
next = curr.Next.Next;
else
break;
}
}
Does it work!?
Because.
say :
1[cur] -> 2[next] -> 3 [temp]-> 4
After the loop
2 -> 1 -> 3[cur] -> 4[next] -> NULL [temp]
and then.
2 -> 1 -> 4 -> 3 -> NULL
That is what we expect right?
But u know. The real thing will be like.
2 -> (1,4) -> 3 -> NULL
Because u didn't change the 1->next link to 4! It still points to 3!
MY VERSION : Click here
here's my c++ code : it will return the pointer to the swapped linked list
Node* swap_list(Node* node) {
if(node == NULL)
return NULL;
Node* ret = node->next;
Node* pre_a = NULL;
Node* a = node;
Node* b = node->next;
while(a!=NULL && b!=NULL) {
a->next = b->next;
b->next = a;
if(pre_a!=NULL)
pre_a->next = b;
pre_a = a;
a = a->next;
if(a==NULL) break;
b = a->next;
}
return ret;
}
private static SList swapAlternateElements(SList n){
if(n == null)
return n;
SList head = swap(n);
SList tail = head;
while(tail == null || tail.next != null){
tail.next.next = swap(tail.next.next);
tail = tail.next.next;
}
return head;
}
private static SList swap(SList n){
if(n.next == null || n==null){
return n;
}
SList current = n.next;
SList next = current.next;
n.next = next;
current.next = n;
return current;
}
I tried to solve it and here is the solution.
public Node swapAdjacentNodes() {
if (head == null)
return null;
if (head.nextNode == null)
return head;
Node previous = null;
Node current = head;
Node next = head.nextNode;
while (next != null && next != current) {
current.nextNode = next.nextNode;
next.nextNode = current;
if (previous == null) {
previous = next;
head = previous;
previous = previous.nextNode;
} else {
previous.nextNode = next;
previous = previous.nextNode.nextNode;
}
current = current.nextNode;
if (current == null)
break;
next = next.nextNode.nextNode.nextNode;
}
return head;
}
Here is my C function to swap links of alternate nodes in linked list.I have included comments in the code. For better understanding take an example and run through the steps by making diagrams using pen and paper.
void swap_alternate_nodes(struct node **head)
{
if(*head==NULL)
return;
if((*head)->next==NULL)
return;
struct node *prev = *head;
struct node *curr = (*head)->next;
struct node *temp = NULL;
*head = (*head)->next; // new head will be second node
while(curr!=NULL && prev!=NULL)
{
if(temp!=NULL)
temp->next = curr; // previous prev node pointer should point to curr pointer
prev->next = curr->next; // update prev node pointer
curr->next = prev; // update curr node pointer
temp = prev; //store prev pointer
prev = prev->next; // forward prev pointer
if(prev)
curr = prev->next; // forward curr pointer
}
}
My take on the solution:-
public Node exchangeAdjacentNodes(Node head){
Node curr = head;
Node temp=null,next=null;
if(curr==null||curr.next==null){
return curr;
Node head = curr.next;
while(curr!=null && curr.next!=null){
next = curr.next;
curr.next=next.next;
temp = curr.next;
next.next = curr;
if(temp!=null && temp.next!=null)
curr.next = curr.next.next;
curr=temp;
}
return head;
}
Here, 'head' is the pointer to the first node of the Linked-List and the function returns the new head pointer.
node* swapPairs(node *head) {
if(head==NULL || head->next==NULL) {
return head;
}
node *ptr1=head->next;
node *ptr2=ptr1->next;
ptr1->next=head;
head->next=swapPairs(ptr2);
return ptr1;
}
public void swapAdjacent() {
temp = head;
while (temp != null && temp.next != null) {
Object tem = temp.val;
temp.val = temp.next.val;
temp.next.val = (Object) tem;
temp = temp.next.next;
}
}
It might help :
public static void main(String[] args) {
String arr[] = { "a", "b", "c", "d", "e", "f" };
int i = 0;
int k = 1;
String temp;
while (k <= arr.length - 1 && arr[i] != null && arr[k] != null) {
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
k++;
i = k;
k++;
}
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[j]+"->");
}
}
// Input -> a->b->c->d->e->f->
// Output -> b->a->d->c->f->e->
C Code to swap Adjacent
node *SwapAdjacent(node *root)
{
*NextNode = NULL;
node * result = root->next;
node *prev = NULL;
while (root != NULL && root->next!=NULL)
{
if(prev!=NULL)
prev->next= root->next;
NextNode = root->next->next;
root->next->next = root;
root->next = NextNode;
prev = root;
root = NextNode;
}
return result;
}