我在为双向链接列表创建交换功能时遇到问题。我只想&#34;重新布线&#34;列表不会改变任何值(我知道这很容易)。我试图创建这个临时项来保持back<-p->front
,这样我就可以将q =设置为正面和背面,但临时项目随p一起变化。如何在没有临时项目的情况下交换这些项目,或者如何让我的临时项目表现出来。
void DLinkedList::swap(Item *p, Item *q)
{
Item* temp = p;
p->next = q->next;
p->pre = q->pre;
if (p->next != NULL)
p->next->pre = p;
if (q->next != NULL)
q->next->pre = q;
q->next = temp->next;
q->pre = temp->pre;
if (p->pre != NULL)
p->pre->next = p;
if (!q->pre == NULL) {
q->pre->next = q;
}
cout << "- The items " << p->val << " & " << q->val << " were swapped -" << endl;
}
答案 0 :(得分:2)
以下是图片形式的情况:
+----------+ +----------+ +----------+
| before_p | <-> | p | <-> | after_p |
+----------+ +----------+ +----------+
+----------+ +----------+ +----------+
| before_q | <-> | q | <-> | after_q |
+----------+ +----------+ +----------+
您遇到的问题是,将temp
指针保存到p
并不会实际复制p
内的指针。因此,当你覆盖它们时,你就会遇到麻烦。
现在,那些&#34;之前&#34; &#34;&#34;&#34;&#34;图片中的项目是你真正想要的。将它们复制出来然后再做逻辑要容易得多。看看以下代码有多清楚:
Item * before_p = p->pre;
Item * before_q = q->pre;
Item * after_p = p->next;
Item * after_q = q->next;
// Relink before and after nodes
if( before_p ) before_p->next = q;
if( before_q ) before_q->next = p;
if( after_p ) after_p->pre = q;
if( after_q ) after_q->pre = p;
// Relink nodes themselves
p->pre = before_q;
q->pre = before_p;
p->next = after_q;
q->next = after_p;
在执行任何事情之前,您可能还需要进行健全性测试:
if( p == q || !p || !q ) return;
最后,如果您在某个地方维护指向列表头部的指针,而这恰好是交换的项目之一,请不要忘记在*之后更新它。
if( head == p ) head = q;
else if( head == q ) head = p;
(*)同样适用于tail
等其他指针。