我的与链表有关的 c 程序有什么问题?

What's wrong with my c program concerned with linked list?

它只是一个用在与链表有关的c程序中的函数。 它的作用是从1,2,3,4,5,...,n这样的列表中挑出第m个数,放到第一位,一般情况下,原来的位置会被删除。 如果我糟糕的英语不能很好地解释我的想法,你可以在程序中得到它。

示例:

输入:7 2

输出:2 1 3 4 5 6 7

输入:7 6

输出:6 1 2 3 4 5 7

输入:7 8

输出:1 2 3 4 5 6 7

现在的问题是它没有正确地 运行 甚至根本没有 运行 当前者的数字小于后者时 one.It 只是出现了一个错误。

  void movenode(SNODE *head, int m)
  {
    SNODE* t,* q;
    t=head;
    int len=0;
    while(t->next!=NULL)
    {
        t=t->next;
        len++;
    }
    //printf("%d",len);
    if(!(m>len||m==0||m==1))
    {
        while(t->next->num!=m)
            t=t->next;
        //printf("%d",t->next->num);
        q=t->next;
        t->next=q->next;
        free(q);
        SNODE * T;
        T = ( SNODE * ) malloc( sizeof( SNODE ) );
        T->next=head->next;
        head->next=T;
        T->num=m;
    }
  }

您的代码有几处错误:

  • 您想遍历列表两次,但不要在第一次遍历后重置迭代指针。这意味着您最终将取消引用 NULL 指针。

  • 您应该决定 m 表示位置还是值。您的代码以某种方式使用了这两个定义,这是不一致的。

  • 您既没有创建新节点,也没有删除旧节点。您只需在同一列表中重新定位现有节点。 (您可以删除旧节点并在列表的前面创建一个具有相同 num 的新节点,但更新指针可能更有效。)

  • 你改变了列表的头部,但是调用代码不会知道这个改变,因为当你 [=73] 时你对 movenodehead 的更新丢失了=] 来自函数。您应该 return 新头部或通过引用传递头部,或者在您作为参考传递的列表周围编写一个包装器结构。

当你考虑你的问题时,你也不需要双循环。当您遍历列表时,跟踪位置并在满足条件时重新排序指针。如果你不能满足你的条件,m超出范围,你什么都不做。

这是一个示例实现:

/*
 *      Move the m-th node in the list to the front. The index 0
 *      refers to the list's head. Returns 1 if a node was moved or
 *      0 otherwise.
 */
int movenode(SNODE **head, int m)
{
    SNODE **t = head;

    if (m < 1) return 0;            /* nothing to do! */

    while ((*t)->next != NULL) {
        if (m == 1) {
            SNODE *p;

            /* extract node */
            p = (*t)->next;
            (*t)->next = p->next;

            /* insert at front */
            p->next = *head;
            *head = p;

            return 1;
        }

        t = &(*t)->next;
        m--;
    }

    return 0;
}

你这样称呼它:

movenode(&head, 1);           /* swap first two nodes */

注意事项:

  • head 作为指向指针的指针传递,即通过引用传递。在你 return 之后, head 将持有新的头部,以便调用代码看到更新后的列表。

  • 迭代器t也是一个指向指针的指针。这就是节点提取工作的原因:您的列表是单链接的,没有指向前一个节点的指针。通过在列表中保留指向该节点的指针地址(最初为 head)并查看下一个节点,您可以在提取节点时更新该指针。

  • 因为迭代的时候看的是下一个节点,所以条件是m == 1,而不是m == 0m 在迭代过程中减少。您也可以保持递增计数(就像您对 len 所做的那样)并将其与 m.

  • 进行比较
  • 函数returns 1或0,表示节点是否被移动