Python Program For Moving All Occurrences Of An Element To End In A Linked List
Last Updated :
01 Feb, 2023
Given a linked list and a key in it, the task is to move all occurrences of the given key to the end of the linked list, keeping the order of all other elements the same.
Examples:
Input : 1 -> 2 -> 2 -> 4 -> 3
key = 2
Output : 1 -> 4 -> 3 -> 2 -> 2
Input : 6 -> 6 -> 7 -> 6 -> 3 -> 10
key = 6
Output : 7 -> 3 -> 10 -> 6 -> 6 -> 6
A simple solution is to one by one find all occurrences of a given key in the linked list. For every found occurrence, insert it at the end. We do it till all occurrences of the given key are moved to the end.
Time Complexity: O(n2)
Efficient Solution 1: is to keep two pointers:
pCrawl => Pointer to traverse the whole list one by one.
pKey => Pointer to an occurrence of the key if a key is found. Else same as pCrawl.
We start both of the above pointers from the head of the linked list. We move pKey only when pKey is not pointing to a key. We always move pCrawl. So, when pCrawl and pKey are not the same, we must have found a key that lies before pCrawl, so we swap between pCrawl and pKey, and move pKey to the next location. The loop invariant is, after swapping of data, all elements from pKey to pCrawl are keys.
Below is the implementation of this approach.
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
def newNode(x):
temp = Node( 0 )
temp.data = x
temp. next = None
return temp
def printList( head):
temp = head
while (temp ! = None ) :
print ( temp.data,end = " " )
temp = temp. next
print ()
def moveToEnd(head, key):
pKey = head
pCrawl = head
while (pCrawl ! = None ) :
if (pCrawl ! = pKey and pCrawl.data ! = key) :
pKey.data = pCrawl.data
pCrawl.data = key
pKey = pKey. next
if (pKey.data ! = key):
pKey = pKey. next
pCrawl = pCrawl. next
return head
head = newNode( 10 )
head. next = newNode( 20 )
head. next . next = newNode( 10 )
head. next . next . next = newNode( 30 )
head. next . next . next . next = newNode( 40 )
head. next . next . next . next . next = newNode( 10 )
head. next . next . next . next . next . next = newNode( 60 )
print ("Before moveToEnd(), the Linked list is
")
printList(head)
key = 10
head = moveToEnd(head, key)
print ("
After moveToEnd(), the Linked list is
")
printList(head)
|
Output:
Before moveToEnd(), the Linked list is
10 20 10 30 40 10 60
After moveToEnd(), the Linked list is
20 30 40 60 10 10 10
Time Complexity: O(n) requires only one traversal of the list.
Space Complexity : O(1)
Efficient Solution 2 :
1. Traverse the linked list and take a pointer at the tail.
2. Now, check for the key and node->data. If they are equal, move the node to last-next, else move ahead.
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
def newNode(x):
temp = Node(x)
return temp
def keyToEnd(head, key):
tail = head
if (head = = None ):
return None
while (tail. next ! = None ):
tail = tail. next
last = tail
current = head
prev = None
prev2 = None
while (current ! = tail):
if (current.data = = key and prev2 = = None ):
prev = current
current = current. next
head = current
last. next = prev
last = last. next
last. next = None
prev = None
else :
if (current.data = = key and prev2 ! = None ):
prev = current
current = current. next
prev2. next = current
last. next = prev
last = last. next
last. next = None
elif (current ! = tail):
prev2 = current
current = current. next
return head
def printList(head):
temp = head
while (temp ! = None ):
print (temp.data, end = ' ' )
temp = temp. next
print ()
if __name__ = = '__main__' :
root = newNode( 5 )
root. next = newNode( 2 )
root. next . next = newNode( 2 )
root. next . next . next = newNode( 7 )
root. next . next . next . next = newNode( 2 )
root. next . next . next . next . next = newNode( 2 )
root. next . next . next . next . next . next = newNode( 2 )
key = 2
print ( "Linked List before operations :" )
printList(root)
print ( "Linked List after operations :" )
root = keyToEnd(root, key)
printList(root)
|
Output:
Linked List before operations :
5 2 2 7 2 2 2
Linked List after operations :
5 7 2 2 2 2 2
Time Complexity: O(n) where n is the size of the given list.
Auxiliary Space: O(1) because it is using constant space
Thanks to Ravinder Kumar for suggesting this method.
Efficient Solution 3: is to maintain a separate list of keys. We initialize this list of keys as empty. We traverse the given list. For every key found, we remove it from the original list and insert it into a separate list of keys. We finally link the list of keys at the end of the remaining given list. The time complexity of this solution is also O(n) and it also requires only one traversal of the list.
Please refer complete article on Move all occurrences of an element to end in a linked list for more details!
Share your thoughts in the comments
Please Login to comment...