我正在尝试编写一种算法,可以在C ++中的单个链表中交换两个节点。这是我到目前为止所拥有的:
void swap(ListNode *node1, ListNode *node2)
{
ListNode *prev1 = head;
ListNode *prev2 = head;
//Search previous node for node1:
while(prev1->next!=node1 || prev1 != node1)
prev1 = prev1->getNext();
//Search previous node for node2:
while(prev2->next!=node2 || prev2 != node2)
prev2 = prev2->getNext();
if(node1->next==node2)
{ //This means node1 == prev2?
tail = node1;
node1->next = NULL;
head = node2;
node2->next = node1;
}
else if(node2->next==node1)
{ // node2 == prev1
tail = node2;
node2->next = NULL;
head = node1;
node1->next = node2;
}
if(node1->next == NULL)
{ //node1 is last
node1->next = node2->next;
tail = node2;
node2->next = NULL;
prev1->next = node2;
prev2->next = node1;
}
}
但是我意识到我可以获得的不同情况的数量,例如,如果LL只有两个元素,或者如果它们在节点1之前给我们节点2等等,我意识到它不可能是这种复杂和丑陋。那么如何编写一个交换两个节点的算法呢?
答案 0 :(得分:2)
在一个例程中执行整个任务是错误的。将其分解为两个更简单的问题:
1)从列表中删除节点,包括所有特殊情况。 2)在列表中插入一个节点,包括所有特殊情况。
从那里开始,整体问题很简单,但由于这显然是家庭作业,所以你可以自己做。
答案 1 :(得分:0)
这对我来说似乎更干净:
//Maybe this function should go instide ListNode itself...
ListNode *prev(ListNode *node) {
if (node == head)
return null;
ListNode *search = head;
while (search != node)
search = search->getNext();
return search;
}
void swap(ListNode *node1, ListNode *node2)
{
ListNode *prev1 = prev(node1),
*prev2 = prev(node2),
*next1 = node1->getNext(),
*next2 = node2->getNext();
if (prev1)
prev1->next = node2;
else
head = node2;
if (prev2)
prev2->next = node1;
else
head = node1;
if (!next1)
tail = node2;
else if (!next2)
tail = node1;
node1->next = next2;
node2->next = next1;
}
没有测试过这个...
答案 2 :(得分:-1)
#include <stdio.h>
struct llist {
struct llist *next;
char *payload;
} llists[]=
{{ llists+1, "one"}
,{ llists+2, "two"}
,{ llists+3, "three"}
,{ llists+4, "four"}
,{ llists+5, "five"}
,{ llists+6, "six"}
,{ llists+7, "seven"}
,{ llists+8, "eight"}
,{ llists+9, "nine"}
,{ NULL, "ten"}
};
struct llist *head = llists;
void llistswap(struct llist *one, struct llist * two)
{
struct llist **hnd, **h1, **h2;
h1 = h2 = NULL;
for (hnd= &head; *hnd; hnd = &(*hnd)->next) {
struct llist *tmp;
if ((*hnd) == one) h1 = hnd;
else if ((*hnd) == two) h2 = hnd;
else continue;
if (!h1 || !h2) continue;
tmp = *h1;
*h1 = *h2;
*h2 = tmp;
tmp = (*h1)->next;
(*h1)->next = (*h2)->next;
(*h2)->next = tmp;
break;
}
}
void do_print(struct llist *lp)
{
for ( ; lp; lp = lp->next) {
printf("%s%c", lp->payload, (lp->next) ?',' : '\n' );
}
}
int main(void)
{
do_print (head);
llistswap ( llists+4, llists+7);
do_print (head);
return 0;
}