简体   繁体   English

交换链表中的节点

[英]Swapping nodes in a linked list

I am trying to swap two adjacent nodes in a linked list, and I think I understand the idea of how to do it using a temporary node. 我正在尝试交换链表中的两个相邻节点,我想我理解如何使用临时节点来实现它。

Here is my struct swap function 这是我的struct swap函数

struct part {
   char* name;
   float price;
   int quantity;
   struct part *next;
};
typedef struct part partType;

partType *swap_node(partType **item) {

  partType *temp;
  temp = *item;
  *item = (*item)->next;
  temp->next = (*item)->next;
  (*item)->next = temp;
  return *item;
}

I cant think of how to make the previous node in the list point to the new swapped node. 我不能想到如何使列表中的前一个节点指向新的交换节点。 Do i need another temp variable? 我需要另一个临时变量吗? Also, how do I account for the case that the two nodes to be swapped are the first two in the list. 另外,如何解释要交换的两个节点是列表中的前两个节点的情况。

From the code, it looks like you want to swap item and item->next. 从代码中,看起来您想要交换项目和项目 - >下一步。

If you don't have a doubly-linked list, then you need to set linkPtr to head, and then iterate until linkPtr->next == *item. 如果您没有双向链表,则需要将linkPtr设置为head,然后迭代直到linkPtr-> next == * item。 From there, you can start switching between linkPtr, linkPtr->next and linkPtr->next->next. 从那里,您可以开始在linkPtr,linkPtr-> next和linkPtr-> next-> next之间切换。

You also need a separate condition comparing linkPtr to head, and if so, then you need to set head to the new head. 你还需要一个单独的条件来比较linkPtr到head,如果是这样,那么你需要设置head到new head。

Ignore the answers about doubly-linked lists. 忽略有关双向链表的答案。 To answer your question, you need to think about how you call your function. 要回答您的问题,您需要考虑如何调用您的函数。

Right now, you have a function that takes a pointer to a pointer. 现在,你有一个带指针指针的函数。 It currently points to a node (node A), which in turn points to another node (node B). 它当前指向一个节点(节点A),该节点又指向另一个节点(节点B)。 Imagine this scenario: 想象一下这种情况:

partType a, b, c, d;
a->next = &b;
b->next = &c;
c->next = &d;
d->next = NULL;

Now, you want to swap the order of B and C to have A->C->B->D using your function. 现在,您想要使用您的函数交换B和C的顺序以使A-> C-> B-> D. Well, you'd do: 好吧,你做的:

swap_node(&a->next);

A was pointing to B; A指着B; now it's pointing to C. As you can see, the "previous" node is already pointing to C, as you expected. 现在它指向C.正如您所看到的,“前一个”节点已经指向C,正如您所期望的那样。 In other words, you've already accomplished your goal. 换句话说,你已经完成了目标。 Cheers! 干杯!

Notes: What exactly is happening in your swap function? 注意:您的交换功能究竟发生了什么? Let's break it down. 让我们分解吧。 First, the parameter you give it is a pointer to a pointer . 首先,您给它的参数是指向指针的指针 Those are a bitch to think about because of the wording -- don't let the wording fool you. 由于措辞的原因,这些都是一个想法的婊子 - 不要让措辞欺骗你。 Just like "rate of change of the rate of change" is a bitch to think about but "acceleration" is much easier. 就像“变化率的变化率”是一个值得思考的婊子,但“加速”更容易。 You want to parse it by remembering that the parameter is, first and foremost, a pointer to some data, and your function is going to modify the data that it points to. 您希望通过记住参数首先是指向某些数据的指针来解析它,并且您的函数将修改它指向的数据。

So your function gets a pointer to this 'p', which is pointing to a spot in the linked list which (you assume, see PS) points to two nodes (call them X and Y). 所以你的函数得到一个指向这个'p'的指针,它指向链表中的一个点(你假设,见PS)指向两个节点(称为X和Y)。 Diagram: 图:

[p] --> X[next] --> Y[next] --> Z[next]

Your algorithm does: 你的算法做了:

  1. Make [p] point to Y: *item = (*item)->next 将[p]指向Y:* item =(* item) - > next
  2. Make X[next] point to Z: temp->next = (*item)->next 使X [next]指向Z:temp-> next =(* item) - > next
  3. Make Y[next] point to X: (*item)->next = temp 使Y [next]指向X:(* item) - > next = temp

So, if you now consider my A, B, C, D example, the linked list was: 所以,如果您现在考虑我的A,B,C,D示例,链表是:

A[next] --> B[next] --> C[next] --> D[next] --> NULL

you can see more clearly what pointer I'm passing. 你可以更清楚地看到我传递的指针。 It's the location in memory (read: pointer) where A[next] is stored, which your function needs to do the swapping. 它是存储器中的位置(读取:指针),其中存储了A [next],您的函数需要进行交换。

Incidentally, another way to code this would be to do: 顺便提一下,另一种编码方式是:

a->next = swap_node(&a->next);

but don't do that. 但不要这样做。 It's redundant. 这是多余的。

PS Have you thought about what happens when you ask to swap the last node in the series? PS你有没有想过当你要求交换系列中的最后一个节点时会发生什么? Right now, things explode :P 现在,事情爆发了:P

With data this small, you might as well just swap everything but the next pointers: 对于这么小的数据,您可能只需交换除next指针之外的所有内容:

partType tmp = *item;
memcpy(item, item->next, offsetof(item, next));
memcpy(item->next, &tmp, offsetof(item, next));

If your data gets too large to do this, you'll need a pointer to the node before the two you want. 如果您的数据太大而无法执行此操作,则需要所需的两个节点之前指向节点。 The nice part is that your fixing of prev 's next pointer acts as a temp variable, letting you not need one. 好的部分是你修复prevnext指针作为临时变量,让你不需要一个。

prev->next = item->next;
item->next = item->next->next;
prev->next->next = item;

Simple way to swap to node... I am not writing actual code. 交换到节点的简单方法......我不是在编写实际的代码。 I am just giving you a hint to swap nodes. 我只是给你一个交换节点的提示。

[1]->[2]->[3]->[4]

Suppose this is your linked list and you want to swap [2] and [3] . 假设这是你的链表,你想交换[2][3]

  1. use loop to reach till [2] . 使用循环达到[2] so your temp is at [2] . 所以你的temp[2]
  2. Now temp1 = temp->next; 现在temp1 = temp->next; Hence temp1 is at [3] . 因此temp1[3]
  3. temp->next = temp1->next;

    temp1->next = temp;

so now temp->next = [4] and temp1->next = [2] 所以现在temp->next = [4]temp1->next = [2]

Four easy options: 四个简单的选择:

First option: Keep track of the pointer to prev (probably the direction the assignment is expected to take). 第一个选项:跟踪指向prev的指针(可能是指向预期的方向)。

Second option: Implement a doubly linked list so that you can always find the previous node. 第二个选项:实现双向链表,以便始终可以找到上一个节点。

Third option: Implement a singly linked list (as your assignment probably calls for), but give each node two pointers: One pointing to 'next', and one pointing to the data payload (which could be just about anything; a struct, an array, or a plain old data type). 第三个选项:实现单链表(如你的任务可能要求的那样),但给每个节点两个指针:一个指向'next',一个指向数据有效负载(可能几乎任何东西;一个结构,一个数组或普通旧数据类型)。 Then you just swap where the payload pointers point without worrying about 'next' and 'prev'. 然后你只需交换有效负载指针指向的位置,而不必担心'next'和'prev'。

A fourth option: Swap the data itself (possibly the direction the assignment is expected to take). 第四种选择:交换数据本身(可能是预期分配的方向)。

There are use cases for each of the above. 上面的每一个都有用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM