链表中的交换节点如何工作

How does swapping nodes in linked list works?

本文关键字:工作 何工作 交换 节点 链表      更新时间:2023-10-16

下面是在不更改数据的情况下交换节点的代码。我想知道是否需要交换节点的下一个指针?交换当前节点不会交换下一个指针吗?为什么?

    void swapNodes(Node** head_ref, int x, int y) 
    { 
        // Nothing to do if x and y are same 
        if (x == y) 
           return; 
        Node **a = NULL, **b = NULL; 
        // search for x and y in the linked list 
        // and store therir pointer in a and b 
        while (*head_ref) { 
              if ((*head_ref)->data == x) { 
                   a = head_ref; 
              } 
              else if ((*head_ref)->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 && b) { 
             swap(*a, *b); 
             swap(((*a)->next), ((*b)->next)); 
         } 
    } 
    void swap(Node*& a, Node*& b) 
    { 
         Node* temp = a; 
         a = b; 
         b = temp; 
    }

谢谢。

是否需要交换节点的下一个指针?

是的,

这是必需的,因为原始节点位于列表的不同位置。

交换

当前节点不会交换下一个指针吗?

是的,交换当前节点不会交换下一个指针。交换当前节点意味着仅交换指向当前节点的指针。

例如,考虑列表

| A |next B| -> | B |next C| -> | C |next D| -> | D |next nullptr|

假设您需要交换节点 B 和 D。然后你会得到

                   ---------------------
                   |                    |
| A |next D| ... | B |next C| -> | C |next B| ... | D |next nullptr|
       |                                            |
       ----------------------------------------------

因此,在第一次交换之后,节点 A 指向节点 D,但节点 D "指向"到 nullptr。节点 B 和 C 如果不交换它们的数据成员,则接下来将丢失。

因此,您接下来还需要交换它们的数据成员

                   --------------------------
                   |                        |
| A |next D| ... | B |next nullptr|   | C |next B| ... | D |next C|
       |                                                 |
       ---------------------------------------------------

结果你会得到

| A |next D| -> | D |next C| -> | C |next B| -> | B |next nullptr|

交换当前节点是不够的。

交换 a 和 b 时,它们的地址会更改,因此它们在列表中的位置将被替换

但您不会更改每个节点的内部字段。

节点图解:

A - B - C - D

让我们以节点 a 和 c 为例。

a->next == &b (True(

c->next == &d (True(

如果我们像这样交换节点:

C - B - A - D

节点 c 和节点 a 的地址将更改,但列表看起来相同,因为它们的 ->next 值不会更改

如果我们也交换 ->next 值,列表将真正被交换