📌  相关文章
📜  用于移动元素的所有出现以在链接列表中结束的Python程序

📅  最后修改于: 2022-05-13 01:56:07.577000             🧑  作者: Mango

用于移动元素的所有出现以在链接列表中结束的Python程序

给定一个链表和其中的一个键,任务是将所有出现的给定键移动到链表的末尾,保持所有其他元素的顺序相同。

例子:

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

一个简单的解决方案是在链表中逐一查找给定键的所有出现。对于每个找到的事件,将其插入到末尾。我们这样做直到给定键的所有出现都移到最后。

时间复杂度: O(n 2 )

有效的解决方案1:是保留两个指针:
pCrawl => 一个一个遍历整个列表的指针。
pKey => 如果找到键,则指向该键的出现。其他与 pCrawl 相同。
我们从链表的头部开始上述两个指针。只有当pKey不指向某个键时,我们才移动pKey 。我们总是移动pCrawl 。所以,当pCrawlpKey不相同时,我们肯定已经找到了一个位于pCrawl之前的 key,所以我们在pCrawlpKey之间交换,并将pKey移动到下一个位置。循环不变量是,在交换数据之后,从pKeypCrawl的所有元素都是键。

下面是这种方法的实现。

Python3
# Python3 program to move all occurrences of a
# given key to end.
  
# Linked List node 
class Node: 
    def __init__(self, data): 
        self.data = data 
        self.next = None
  
# A utility function to create a new node.
def newNode(x):
  
    temp = Node(0)
    temp.data = x
    temp.next = None
    return temp
  
# Utility function to print the elements
# in Linked list
def printList( head):
  
    temp = head
    while (temp != None) :
        print( temp.data,end = " ")
        temp = temp.next
      
    print()
  
# Moves all occurrences of given key to
# end of linked list.
def moveToEnd(head, key):
  
    # Keeps track of locations where key
    # is present.
    pKey = head
  
    # Traverse list
    pCrawl = head
    while (pCrawl != None) :
          
        # If current pointer is not same as pointer
        # to a key location, then we must have found
        # a key in linked list. We swap data of pCrawl
        # and pKey and move pKey to next position.
        if (pCrawl != pKey and pCrawl.data != key) :
            pKey.data = pCrawl.data
            pCrawl.data = key
            pKey = pKey.next
          
        # Find next position where key is present
        if (pKey.data != key):
            pKey = pKey.next
  
        # Moving to next Node
        pCrawl = pCrawl.next
      
    return head
  
# Driver code
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)
  
# This code is contributed by Arnab Kundu


Python3
# Python3 code to remove key element to
# end of linked list
   
# A Linked list Node
class Node:
      
    def __init__(self, data):
          
        self.data = data
        self.next = None
          
# A utility function to create a new node.
def newNode(x):
      
    temp = Node(x)
    return temp
  
# Function to remove key to end
def keyToEnd(head, key):
  
    # Node to keep pointing to tail
    tail = head
      
    if (head == None):
        return None
      
    while (tail.next != None): 
        tail = tail.next
      
    # Node to point to last of linked list
    last = tail
    current = head
    prev = None
       
    # Node prev2 to point to previous
    # when head.data!=key
    prev2 = None
       
    # Loop to perform operations to 
    # remove key to end
    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
  
# Function to display linked list
def printList(head):
  
    temp = head
      
    while (temp != None):
        print(temp.data, end = ' ')
        temp = temp.next
      
    print()
      
# Driver Code
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)
      
# This code is contributed by rutvik_56


输出:

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

时间复杂度: O(n) 只需要遍历一次列表。

高效解决方案 2:
1. 遍历链表,在尾部取一个指针。
2. 现在,检查密钥和节点->数据。如果它们相等,则将节点移动到 last-next,否则继续前进。

Python3

# Python3 code to remove key element to
# end of linked list
   
# A Linked list Node
class Node:
      
    def __init__(self, data):
          
        self.data = data
        self.next = None
          
# A utility function to create a new node.
def newNode(x):
      
    temp = Node(x)
    return temp
  
# Function to remove key to end
def keyToEnd(head, key):
  
    # Node to keep pointing to tail
    tail = head
      
    if (head == None):
        return None
      
    while (tail.next != None): 
        tail = tail.next
      
    # Node to point to last of linked list
    last = tail
    current = head
    prev = None
       
    # Node prev2 to point to previous
    # when head.data!=key
    prev2 = None
       
    # Loop to perform operations to 
    # remove key to end
    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
  
# Function to display linked list
def printList(head):
  
    temp = head
      
    while (temp != None):
        print(temp.data, end = ' ')
        temp = temp.next
      
    print()
      
# Driver Code
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)
      
# This code is contributed by rutvik_56

输出:

Linked List before operations :
5 2 2 7 2 2 2 
Linked List after operations :
5 7 2 2 2 2 2

感谢Ravinder Kumar提出这种方法。

高效的解决方案3:是维护一个单独的键列表。我们将此键列表初始化为空。我们遍历给定的列表。对于找到的每个键,我们将其从原始列表中删除并将其插入到单独的键列表中。我们最终将键列表链接到剩余给定列表的末尾。该解决方案的时间复杂度也是 O(n),而且它也只需要遍历一次列表。

有关详细信息,请参阅有关将所有出现的元素移动到链接列表中的完整文章!