📌  相关文章
📜  用于在不交换数据的情况下交换链表中的节点的Python程序

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

用于在不交换数据的情况下交换链表中的节点的Python程序

给定一个链表和其中的两个键,交换两个给定键的节点。节点应该通过改变链接来交换。当数据包含许多字段时,在许多情况下交换节点的数据可能会很昂贵。

可以假设链表中的所有键都是不同的。

例子:

Input : 10->15->12->13->20->14,  x = 12, y = 20
Output: 10->15->20->13->12->14

Input : 10->15->12->13->20->14,  x = 10, y = 20
Output: 20->15->12->13->10->14

Input : 10->15->12->13->20->14,  x = 12, y = 13
Output: 10->15->13->12->20->14

这可能看起来是一个简单的问题,但却是一个有趣的问题,因为它需要处理以下情况。

  1. x 和 y 可能相邻也可能不相邻。
  2. x 或 y 都可以是头节点。
  3. x 或 y 可能是最后一个节点。
  4. x 和/或 y 可能不存在于链表中。

如何编写一个干净的工作代码来处理上述所有可能性。

这个想法是首先在给定的链表中搜索 x 和 y。如果其中任何一个都不存在,则返回。在搜索 x 和 y 时,跟踪当前和以前的指针。首先更改前一个指针的下一个,然后更改当前指针的下一个。

下面是上述方法的实现。

Python
# Python program to swap two given nodes
# of a linked list
class LinkedList(object):
    def __init__(self):
        self.head = None
 
    # Head of list
    class Node(object):
        def __init__(self, d):
            self.data = d
            self.next = None
 
    # Function to swap Nodes x and y
    # in a linked list by changing links
    def swapNodes(self, x, y):
 
        # Nothing to do if x and y are
        # the same
        if x == y:
            return
 
        # Search for x (keep track of
        # prevX and CurrX)
        prevX = None
        currX = self.head
        while currX != None and currX.data != x:
            prevX = currX
            currX = currX.next
 
        # Search for y (keep track of
        # prevY and currY)
        prevY = None
        currY = self.head
        while currY != None and currY.data != y:
            prevY = currY
            currY = currY.next
 
        # If either x or y is not present,
        # nothing to do
        if currX == None or currY == None:
            return
 
        # If x is not head of linked list
        if prevX != None:
            prevX.next = currY
 
        else:  # make y the new head
            self.head = currY
 
        # If y is not head of linked list
        if prevY != None:
            prevY.next = currX
        else: 
 
            # make x the new head
            self.head = currX
 
        # Swap next pointers
        temp = currX.next
        currX.next = currY.next
        currY.next = temp
 
    # Function to add Node at beginning
    # of list.
    def push(self, new_data):
 
        # 1. alloc the Node and put the data
        new_Node = self.Node(new_data)
 
        # 2. Make next of new Node as head
        new_Node.next = self.head
 
        # 3. Move the head to point to new Node
        self.head = new_Node
 
    # This function prints contents of
    # linked list starting from the given Node
    def printList(self):
        tNode = self.head
        while tNode != None:
            print tNode.data,
            tNode = tNode.next
 
# Driver code
llist = LinkedList()
 
# The constructed linked list is:
# 1->2->3->4->5->6->7
llist.push(7)
llist.push(6)
llist.push(5)
llist.push(4)
llist.push(3)
llist.push(2)
llist.push(1)
print "Linked list before calling swapNodes() "
llist.printList()
llist.swapNodes(4, 3)
print "
Linked list after calling swapNodes() "
llist.printList()
# This code is contributed by BHAVYA JAIN


Python
# Python3 program to swap two given
# nodes of a linked list
 
# A linked list node class
class Node:
 
    # constructor
    def __init__(self, val = None,
                 next1 = None):
        self.data = val
        self.next = next1
 
    # Print list from this
    # to last till None
    def printList(self):
        node = self
 
        while (node != None):
            print(node.data, end = " ")
            node = node.next
        print(" ")
 
# Function to add a node
# at the beginning of List
def push(head_ref, new_data):
 
    # Allocate node
    (head_ref) = Node(new_data, head_ref)
    return head_ref
 
def swapNodes(head_ref, x, y):
    head = head_ref
 
    # Nothing to do if x and y are same
    if (x == y):
        return None
 
    a = None
    b = None
 
    # Search for x and y in the linked list
    # and store their pointer in a and b
    while (head_ref.next != None):
 
        if ((head_ref.next).data == x):
            a = head_ref
 
        elif ((head_ref.next).data == y):
            b = head_ref
 
        head_ref = ((head_ref).next)
 
    # If we have found both a and b
    # in the linked list swap current
    # pointer and next pointer of these
    if (a != None and b != None):
        temp = a.next
        a.next = b.next
        b.next = temp
        temp = a.next.next
        a.next.next = b.next.next
        b.next.next = temp
 
    return head
 
# Driver code
start = None
 
# The constructed linked list is:
# 1.2.3.4.5.6.7
start = push(start, 7)
start = push(start, 6)
start = push(start, 5)
start = push(start, 4)
start = push(start, 3)
start = push(start, 2)
start = push(start, 1)
 
print("Linked list before calling swapNodes() ")
start.printList()
start = swapNodes(start, 6, 1)
print("Linked list after calling swapNodes() ")
start.printList()
# This code is contributed by Arnab Kundu


输出:

Linked list before calling swapNodes() 1 2 3 4 5 6 7 
Linked list after calling swapNodes() 1 2 4 3 5 6 7 

时间复杂度:O(n)

辅助空间:O(1)

优化:上面的代码可以优化为在单次遍历中搜索 x 和 y。两个循环用于保持程序简单。

更简单的方法:

Python

# Python3 program to swap two given
# nodes of a linked list
 
# A linked list node class
class Node:
 
    # constructor
    def __init__(self, val = None,
                 next1 = None):
        self.data = val
        self.next = next1
 
    # Print list from this
    # to last till None
    def printList(self):
        node = self
 
        while (node != None):
            print(node.data, end = " ")
            node = node.next
        print(" ")
 
# Function to add a node
# at the beginning of List
def push(head_ref, new_data):
 
    # Allocate node
    (head_ref) = Node(new_data, head_ref)
    return head_ref
 
def swapNodes(head_ref, x, y):
    head = head_ref
 
    # Nothing to do if x and y are same
    if (x == y):
        return None
 
    a = None
    b = None
 
    # Search for x and y in the linked list
    # and store their pointer in a and b
    while (head_ref.next != None):
 
        if ((head_ref.next).data == x):
            a = head_ref
 
        elif ((head_ref.next).data == y):
            b = head_ref
 
        head_ref = ((head_ref).next)
 
    # If we have found both a and b
    # in the linked list swap current
    # pointer and next pointer of these
    if (a != None and b != None):
        temp = a.next
        a.next = b.next
        b.next = temp
        temp = a.next.next
        a.next.next = b.next.next
        b.next.next = temp
 
    return head
 
# Driver code
start = None
 
# The constructed linked list is:
# 1.2.3.4.5.6.7
start = push(start, 7)
start = push(start, 6)
start = push(start, 5)
start = push(start, 4)
start = push(start, 3)
start = push(start, 2)
start = push(start, 1)
 
print("Linked list before calling swapNodes() ")
start.printList()
start = swapNodes(start, 6, 1)
print("Linked list after calling swapNodes() ")
start.printList()
# This code is contributed by Arnab Kundu

输出:

Linked list before calling swapNodes() 1 2 3 4 5 6 7 
Linked list after calling swapNodes() 6 2 3 4 5 1 7 

时间复杂度:O(n)

辅助空间:O(1)

请参考完整的文章在链表中交换节点而不交换数据以获取更多详细信息!