【问题标题】:Confusion on pointers C (Linked list)对指针 C 的混淆(链表)
【发布时间】:2013-07-07 03:45:19
【问题描述】:

我正在尝试交换链表中两个相邻节点的地址。 我尝试使用 int temp 变量交换它们的值,并且效果很好。 但是现在,我想通过指针交换两个地址。不幸的是,它在我的 while 循环中创建了一个无限循环。这是我的代码 sn-p:

使用 int: //工作得很好

node* swapNumbers(node* head, int data){
    int temp;
    node *cursor = head;

    while(cursor!=NULL){
        if(cursor->data == data){
            temp = cursor->data;
            cursor->data = cursor->next->data;
            cursor->next->data = temp;
            //printf("1: %d\n", cursor->data);
            //printf("2: %d\n", cursor->next->data);

            return cursor;      
        } 
        cursor = cursor->next;
    }
    return NULL;
}

使用地址://这创建了一个无限循环!

node* swapNumbers(node* head, int data){
    node *temp = NULL;
    node *cursor = head;

    while(cursor!=NULL){
        if(cursor->data == data){
            temp = cursor;
            cursor = cursor->next;
            cursor->next = temp;
        return cursor;      
        } 
        cursor = cursor->next;
    }
    return NULL;
}

我的 typedef 结构包含以下内容:

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

我是 C 新手,指针仍然让我感到困惑。任何帮助将不胜感激!

【问题讨论】:

  • 画图——用线条和箭头表示下一个指针。为了反转链表中的两个节点,您必须更改 previous 节点中的指针(如果没有前一个节点,则更改链表头),以及交换的两个节点。跨度>
  • 你在这里找到答案:Swap nodes in a singly-linked list

标签: c list pointers linked-list


【解决方案1】:

为了不进入无限循环,你需要将cursor的前身值保存在另一个指针指向的临时值中。

【讨论】:

    【解决方案2】:

    我可以建议一种简单的方法来交换单链表中的两个节点吗?

    /* p points to the node before a, a and b are the nodes to be swapped */
    void swap_address(node* p, node* a, node* b) 
    {
        node* n = b->next; /* save the address of the node after b */
    
        if (!p || !a || !b)
        {
            printf("One of the arguments is NULL!\n");
            return;
        }
    
        p->next = b; /* p points to b */
        b->next = a; /* b points to a */
        a->next = n; /* a points to the node that was originally after b */
    }
    

    在我的机器上,我尝试了以下结构定义:

    typedef struct node
    {
        struct node* next;
        int val;
    } node;
    

    我是这样使用它的:

    swap_address(b, c, d);
    

    我有节点 head -> a -> b -> c -> d 按此顺序具有值 1、2、3 和 4。

    交换后顺序变为1 -> 2 -> 4 -> 3。

    这就是你所追求的吗?

    【讨论】:

    • 请注意,这不是有效的 C89,需要 C99+ 才能工作。声明后有声明。
    • @Jite 我没有意识到这是一个要求,但很公平,我已经在块的开头移动了声明。
    【解决方案3】:

    您必须在代码中处理三种情况。

    1. 如果数据节点是第一个节点。您必须更改头指针。由于您只传递指针,因此您无法更改头部是第二个元素。

    2. 如果数据节点是最后一个节点。不能兑换。

    3. 如果数据节点是中间节点。您需要以前的光标,因此您可以将其指向正确的节点。 假设你有 prev 节点

          if(cursor->data == data)
          {
              temp = cursor;
              cursor = cursor->next;
              if (NULL == cursor)
                  return NULL;
              temp->next = cursor->next;
              prev->next = cursor;
              cursor->next = temp;
              return cursor;      
          } 
      

    【讨论】:

    • 你有一个“.”代替 ”;”在一行的末尾
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 2010-09-25
    • 2011-09-04
    • 2016-11-08
    • 2018-10-07
    • 1970-01-01
    相关资源
    最近更新 更多