【问题标题】:Swap the linklist nodes in c elegantly优雅地交换 c 中的链表节点
【发布时间】:2018-03-15 11:17:53
【问题描述】:

我想交换 Linklist 中的节点。

我写了函数swap,但是当节点旁边的节点时它不起作用。

例如,我想交换 node4 和 node5。错了。

void swap (int pos1, int pos2, LINK *head)
{
  LINK* pre_node1 = search(pos1-1, head);
  LINK* pre_node2 = search(pos2-1, head);

  LINK* current_node1 = pre_node1 -> next;
  LINK* current_node2 = pre_node2 -> next;

  LINK* next_node1 = search(pos1+1, head);
  LINK* next_node2 = search(pos2+1, head);

  pre_node1 -> next = current_node2;
  pre_node2 -> next = current_node1;

  current_node1 -> next = next_node2;
  current_node2 -> next = next_node1;
}

我测试功能:

    for (int i=1; i < 10; i++)
      insert(i,head,i);
    printf ("original array: \n");
    print(head);

    printf ("swap node2 and node7: \n");
    swap(2,7,head);
    print(head);

    printf ("swap node1 and node9: \n");
    swap(1,9,head);
    print(head);

/*
    It does not work!
    swap(4,5,head);
    print(head);
*/

我可以使用swap2 交换内容。但我觉得它很丑。

void swap2 (int pos1, int pos2, LINK *head)
{
  LINK* node1 = search(pos1, head);
  LINK* node2 = search(pos2, head);
  int tem = node1->data;
  node1->data = node2->data;
  node2->data = tem;
}

我想交换节点。请告诉我如何更正swap

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct linklist {
  int data;
  struct linklist * next;
}LINK;

LINK* createnode (int element,LINK *first);
LINK* search (int j,LINK *head);
void insert (int ele, LINK *head, int pos);
void delete (LINK *head, int pos);
void print (LINK *head);
void swap (int pos1, int pos2, LINK *head);
void swap2 (int pos1, int pos2, LINK *head);
void swap3(int i,int j,LINK *head);

int main(int argc, char ** argv)
{
    LINK *head;
    head = (LINK *)malloc(sizeof(LINK));
    head-> next = NULL;

    for (int i=1; i < 10; i++)
      insert(i,head,i);
    printf ("original array: \n");
    print(head);

    printf ("swap node2 and node7: \n");
    swap(2,7,head);
    print(head);

    printf ("swap node1 and node9: \n");
    swap(1,9,head);
    print(head);
/*
    It does not work!
    swap(4,5,head);
    print(head);
*/

/*
  The function swap2 only swap the data, I want swap the nodes.
    printf ("swap node4 and node5: \n");
    swap2(4,5,head);
    print(head);
*/
    printf ("swap node4 and node5: \n");
    swap3(4,5,head);
    print(head);

}

LINK* createnode(int element,LINK *first)
{
    LINK *ele;
    ele = (LINK *)malloc(sizeof(LINK));
    ele -> data = element;
    ele -> next = first -> next;
    first -> next = ele;
    return first;
}

LINK* search (int j,LINK * head)
{
    LINK *tem;
    tem = head;
    int i = 0;
    while (tem -> next !=NULL && i < j)
    {
        tem = tem->next;
        i++;
    }
    if (tem != NULL && i==j)
        return tem;
    else return NULL;
}

void insert (int ele, LINK *head, int pos)
{
    LINK *prenode = search(pos-1,head);
    LINK *d = createnode(ele, prenode);
    if (prenode == NULL)
      printf ("insert error! \n");
}

void delete (LINK *head, int pos)
{
    LINK *prenode = search (pos-1,head);
    if (prenode != NULL)
    {
        LINK *nownode = prenode -> next;
        prenode -> next = nownode -> next;
        free(nownode);
    }
    else  printf("delete error!\n");
}

void print (LINK* head)
 {
     int j=0;
     LINK *p;
     p = head->next;
     while (p != NULL)
     {
         printf("%d ", p->data);
         p = p -> next;
         j++;
     }
     printf ("\n");
}

void swap (int pos1, int pos2, LINK *head)
{
  LINK* pre_node1 = search(pos1-1, head);
  LINK* pre_node2 = search(pos2-1, head);

  LINK* current_node1 = pre_node1 -> next;
  LINK* current_node2 = pre_node2 -> next;

  LINK* next_node1 = search(pos1+1, head);
  LINK* next_node2 = search(pos2+1, head);

  pre_node1 -> next = current_node2;
  pre_node2 -> next = current_node1;

  current_node1 -> next = next_node2;
  current_node2 -> next = next_node1;
}

void swap2 (int pos1, int pos2, LINK *head)
{
  LINK* node1 = search(pos1, head);
  LINK* node2 = search(pos2, head);
  int tem = node1->data;
  node1->data = node2->data;
  node2->data = tem;
}

void swap3(int i,int j,LINK *head)
{
    LINK* previous_i = search(i-1,head);
    LINK* previous_j =  search(j-1,head);
    LINK* adress_i = search(i,head);
    LINK* adress_j = search(j,head);
    LINK* latter_i = search(i+1,head);
    LINK* latter_j = search(j+1,head);

    if (adress_i->next != adress_j && adress_j->next != adress_i)
    {
    previous_i -> next = adress_j;
    adress_j -> next = latter_i;
    previous_j -> next = adress_i;
    adress_i -> next = latter_j;
    }
    else if (adress_i->next == adress_j)
    {
        previous_i -> next = adress_j;
        adress_j -> next = adress_i;
        adress_i ->next = latter_j;
    }
    else if (adress_j->next == adress_i)
    {
        previous_j -> next = adress_i;
        adress_i -> next = adress_j;
        adress_j ->next = latter_i;
    }
}

最后,我写了swap3。但我认为它是如此复杂。没错。

void swap3(int i,int j,LINK *head)
{
    LINK* previous_i = search(i-1,head);
    LINK* previous_j =  search(j-1,head);
    LINK* adress_i = search(i,head);
    LINK* adress_j = search(j,head);
    LINK* latter_i = search(i+1,head);
    LINK* latter_j = search(j+1,head);

    if (adress_i->next != adress_j && adress_j->next != adress_i)
    {
    previous_i -> next = adress_j;
    adress_j -> next = latter_i;
    previous_j -> next = adress_i;
    adress_i -> next = latter_j;
    }
    else if (adress_i->next == adress_j)
    {
        previous_i -> next = adress_j;
        adress_j -> next = adress_i;
        adress_i ->next = latter_j;
    }
    else if (adress_j->next == adress_i)
    {
        previous_j -> next = adress_i;
        adress_i -> next = adress_j;
        adress_j ->next = latter_i;
    }
}

提前致谢。

【问题讨论】:

  • 删除一个节点,您需要更改两个指针(插入相同) 要交换两个节点,您需要两次删除+两次插入。哪个?纸+铅笔:画画。
  • 谢谢。我解决问题。我将代码添加到问题中。但我认为它是如此复杂。
  • 使用调试器逐步查看不工作的实现与预期不同的地方。
  • 谢谢。我用铅笔和纸解决了这个问题。我的代码是正确的。我的想法是错误的。想想你的建议。 @MrSmith42
  • .(点)和-&gt;(箭头)运算符绑定非常紧密,不应在它们的任何一侧写入空格——仅限structure.memberpointer-&gt;member。跨度>

标签: c algorithm data-structures


【解决方案1】:

我想有更清洁的方法可以解决这个问题,但这是我的 tw 美分: 测试:

swap(2,7,head);
swap(1,9,head);
swap(4,5,head);
swap(6,5,head);

void swap (int pos1, int pos2, LINK *head)
{
    LINK* pre_node1 = search(pos1-1, head);
    LINK* pre_node2 = search(pos2-1, head);

    LINK* current_node1 = pre_node1 -> next;
    LINK* current_node2 = pre_node2 -> next;

    LINK* next_node1 = search(pos1+1, head);
    LINK* next_node2 = search(pos2+1, head);

        pre_node1 -> next = current_node2;
        pre_node2->next = current_node1;

    if (current_node1 != next_node2)
        current_node1 -> next = next_node2;
    else
        current_node1 -> next = current_node2;
    if (current_node2 != next_node1)
        current_node2->next = next_node1;
    else
        current_node2->next = current_node1;
}

【讨论】:

  • @Dagan 如果一个交换节点是头,我看不到头在哪里改变。
  • @VladfromMoscow 如果我正确理解原始代码 head 是静态的并且始终用作第一个元素 - 此解决方案指的是此限制 - 如果我错了或不想在此实施方式那么你是正确的 - 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-18
  • 2017-12-07
  • 2018-11-05
  • 1970-01-01
  • 2014-04-17
相关资源
最近更新 更多