【问题标题】:Pair wise swap in link list in c++C ++中链表中的成对交换
【发布时间】:2019-03-18 18:17:38
【问题描述】:
void pairWiseSwap(struct node *head)
{
// The task is to complete this method
   if(!head || (head && head->next==NULL))
   return;

   if(head->next!=NULL)
   {
     int tmp = head->next->data;
     head->next->data = head->data;
     head->data = tmp;
     pairWiseSwap(head->next->next);
   }
 }

成对交换元素。 这段代码是如何工作的? 反向递归调用是如何工作的?

【问题讨论】:

  • 为什么不std::swap
  • ...因为这是 C 代码而不是 C++
  • 你对这段代码有什么不明白的地方?它在做什么是你不期望的,你期望什么?
  • 旁注:head 运算符右侧的head 不需要重新检查。 C 和 C++ 标准都保证如果逻辑 OR 运算符的左侧计算结果为真,则不计算右侧。因此(!head || head->next==NULL) 是安全的,除非你的编译器不符合标准。

标签: c pointers linked-list


【解决方案1】:

正如函数名称所说,它交换每对单元格中的数据(而不是单元格本身)。


一个单元格与下一个单元格的数据交换非常明显:

int tmp = head->next->data;
head->next->data = head->data;
head->data = tmp;

反向递归调用是如何工作的?

pairWiseSwap(head->next->next); 的调用绕过了数据被交换的几个单元格以重做下一个单元格。


让我们看一个完整代码的例子:

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

struct node {
  struct node * next;
  int data;
};

void pairWiseSwap(struct node *head)
{
// The task is to complete this method
   if(!head || (head && head->next==NULL))
     return;

   if(head->next!=NULL)
   {
     int tmp = head->next->data;
     head->next->data = head->data;
     head->data = tmp;
     pairWiseSwap(head->next->next);
   }
}

struct node * mk(int d, struct node * nx)
{
  struct node * n = malloc(sizeof(struct node));

  if (n != NULL) {
    n->data = d;
    n->next = nx;
  }

  return n;
}

void pr(struct node * head)
{
  while (head) {
    printf("%d ", head->data);
    head = head->next;
  }
}

int main()
{
  struct node * head = mk(0, mk(1, mk(2, mk(3, mk(4, mk(5, NULL))))));

  printf("before : ");
  pr(head);

  pairWiseSwap(head);
  printf("\nafter:   ");
  pr(head);
  putchar('\n');

  /* free resources */
  while (head) {
    struct node * n = head->next;

    free(head);
    head = n;
  }
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra h.c
pi@raspberrypi:/tmp $ ./a.out
before : 0 1 2 3 4 5 
after:   1 0 3 2 5 4 

注意

if(!head || (head && head->next==NULL))
  return;

可以只是

if ((head == NULL) || (head->next==NULL))
  return;

因为如果 head|| 的左侧不为空,则再次检查它在右侧不为空是没用的


如果递归是在 head-&gt;next 而不是 head-&gt;next-&gt;next 上完成的,则函数会进行一种旋转,结果是 1 2 3 4 5 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多