交换链表中的节点

时间:2012-04-02 03:25:36

标签: c struct linked-list

我正在尝试交换链表中的两个相邻节点,我想我理解如何使用临时节点来实现它。

这是我的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;
}

我无法想到如何使列表中的上一个节点指向新的交换节点。我需要另一个临时变量吗?另外,如何解释要交换的两个节点是列表中的前两个节点的情况。

5 个答案:

答案 0 :(得分:1)

从代码中,您似乎想要交换项目和项目 - >接下来。

如果您没有双向链表,那么您需要将linkPtr设置为head,然后迭代直到linkPtr-> next == * item。从那里,您可以开始在linkPtr,linkPtr-> next和linkPtr-> next-> next之间切换。

你还需要一个单独的条件来比较linkPtr到head,如果是这样,那么你需要设置head到新头。

答案 1 :(得分:1)

忽略有关双向链接列表的答案。要回答你的问题,你需要考虑如何称呼你的功能。

现在,你有一个带指针指针的函数。它当前指向一个节点(节点A),该节点又指向另一个节点(节点B)。想象一下这种情况:

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

现在,您想要使用您的函数交换B和C的顺序以使A-> C-> B-> D。好吧,你会这样做:

swap_node(&a->next);
A指着B;现在它指向C.正如您所看到的,“前一个”节点已经指向C,正如您所期望的那样。换句话说,你已经完成了目标。干杯!

注意:您的交换功能究竟发生了什么?让我们分解吧。首先,您提供的参数是指向的指针。由于措辞的原因,这些都是一个想法的婊子 - 不要让措辞欺骗你。就像“变化率的变化率”是一个值得思考的婊子,但“加速”更容易。您希望通过记住参数首先是指向某些数据的指针来解析它,并且您的函数将修改它指向的数据。

所以你的函数得到一个指向这个'p'的指针,它指向链表中的一个点(你假设,见PS)指向两个节点(称为X和Y)。图:

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

您的算法确实:

  1. 将[p]指向Y:* item =(* item) - > next
  2. 使X [next]指向Z:temp-> next =(* item) - > next
  3. 使Y [next]指向X:(* item) - > next = temp
  4. 所以,如果你现在考虑我的A,B,C,D例子,链表是:

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

    你可以更清楚地看到我正在传递的指针。它是存储器中的位置(读取:指针),其中存储了A [next],您的函数需要进行交换。

    顺便提一下,另一种编码方式是:

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

    但不要这样做。这是多余的。

    PS 您是否考虑过要求交换系列中的最后一个节点时会发生什么?现在,事情爆发了:P

答案 2 :(得分:1)

如果数据很小,你可以只交换除next指针之外的所有内容:

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

如果您的数据太大而无法执行此操作,则需要指向节点之前的指针。好的部分是你修复prev的{​​{1}}指针作为临时变量,让你不需要。{/ p>

next

答案 3 :(得分:1)

交换到节点的简单方法...... 我不是在写实际的代码。我只是给你一个交换节点的提示。

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

假设这是您的链接列表,并且您想要交换[2][3]

  1. 使用循环到达[2]。所以temp位于[2]
  2. 现在temp1 = temp->next;因此temp1位于[3]
  3. temp->next = temp1->next;

    temp1->next = temp;

  4. 所以现在temp->next = [4]temp1->next = [2]

答案 4 :(得分:0)

四个简单的选择:

第一个选项:跟踪指向prev的指针(可能是分配预期的方向)。

第二个选项:实现双向链接列表,以便始终可以找到上一个节点。

第三个选项:实现单链表(正如你的任务可能要求的那样),但给每个节点两个指针:一个指向'next',一个指向数据有效负载(可能几乎任何东西; a struct,数组或普通旧数据类型)。然后你只需交换有效负载指针指向的位置,而不必担心'next'和'prev'。

第四个选项:交换数据本身(可能是预期分配的方向)。

以上各项都有用例。