C ++链接列表交换节点

时间:2012-03-04 16:06:49

标签: c++ algorithm linked-list swap

  

可能重复:
  debug help - swap 2 nodes of double link list

我正在尝试编写一种算法,可以在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等等,我意识到它不可能是这种复杂和丑陋。那么如何编写一个交换两个节点的算法呢?

3 个答案:

答案 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;
}