【问题标题】:How to reverse a single-linked list in C?如何在C中反转单​​链表?
【发布时间】:2016-04-22 18:11:49
【问题描述】:

对于我的班级,我的任务是构建一个链表、输入数据并执行不同的功能。我的代码编译正常,但是反转和建设性反转功能不起作用。

如果我反转列表并打印它,我只会得到第一个节点。 我似乎在某处错过了重点。这是我的代码: (如果您发现任何其他功能有任何错误,请告诉我) 提前致谢!

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

typedef struct DoubleNode{
    struct DoubleNode* next;
    double data;

} DoubleNode;

DoubleNode* insertFirst(DoubleNode*head, double c) {
    DoubleNode* temp;
    temp=malloc(sizeof(DoubleNode));
    temp->data= c;
    temp->next= head;

    return temp;
}
void printList(DoubleNode*head) {
    DoubleNode* cursor;
    printf("(");
    cursor=head;
    while (cursor != NULL) {
        printf("%fl", cursor->data);
        printf(" ");
        cursor=cursor->next;
    }
    printf(")");
}


DoubleNode* insertLast(DoubleNode *head, double d) {
    DoubleNode *tmp, *cursor;
    //trivial case: empty list
    if (head==NULL)
    {return insertFirst(head,d);
    } else{
        //general case: goto end
        cursor=head;
        while (cursor->next != NULL){
            cursor =cursor->next;
        }
        tmp= malloc(sizeof(DoubleNode));
        tmp->data = d;
        tmp->next = NULL;
        cursor->next=tmp;
        return head;
    }
}

DoubleNode* reverseDoubleListCon(DoubleNode*head) {
    DoubleNode *temp, *res, *cell;
    cell=head;
    res=NULL;
    while (cell!=NULL) {
        temp=malloc(sizeof(DoubleNode));
        temp->data=cell->data;
        temp->next=res;
        res=temp;
        cell=cell->next;
    }
    return res;
}

void reverseDoubleList(DoubleNode*head) {
    DoubleNode *chain, *revChain, *cell;
    cell=head;
    revChain=NULL;
    while (cell!=NULL) {
        chain=cell->next;
        cell->next=revChain;
        revChain=cell;
        cell=chain;
    }
    head=revChain;
}

double get(DoubleNode*head, double n) {
    DoubleNode *cursor;
    cursor=head;
    for (int i=0; i<n; i++) {
        cursor=cursor->next;

    }
    return cursor->data;
}

DoubleNode* delete(DoubleNode*head, double n) {
    DoubleNode *cursor, *rest;
    cursor=head;
    for (int i=0; i<n; i++) {
        cursor=rest;
        cursor=cursor->next;

    }
    rest->next=cursor->next;
    free(cursor);
    return head;

}

DoubleNode* insert(DoubleNode*head, double d, double n) {
    DoubleNode *cursor, *temp, *rest;
    cursor=head;

    for (int i = 0; i<n-1; i++) {
        rest=cursor;
        cursor= cursor->next;
    }
    temp=malloc(sizeof(DoubleNode));
    temp->data=d;
    temp->next=cursor;
    rest->next= temp;

    return head;
}

int main(int argc, const char * argv[]) {
    DoubleNode *head;
    head=malloc(sizeof(DoubleNode));

    for (double i=0.0; i <11.0; i++) {
        head=insertLast(head, i);
    }
    printList(head);
    reverseDoubleList(head);
    printList(head);
    reverseDoubleListCon(head);
    printList(head);

    return 0;
}

【问题讨论】:

  • 你觉得head=revChain会在函数之外有什么作用吗?
  • 我相信它将指针头设置为列表的新第一个元素。我错了吗?
  • 改成void reverseDoubleList(DoubleNode* &amp; head)
  • @WhatsUp 这是 C,不是 C++
  • @Chris3101 问题是您已经通过值传递了头指针(*head 而不是 **head),这意味着如果您更改它的值(而不是它指向的值) to) 函数内,函数返回时无效。

标签: c linked-list singly-linked-list


【解决方案1】:

这将适用于您的反向功能。

void reverseDoubleList(DoubleNode **head) {
    DoubleNode *prev, *curr, *next;
    curr=*head;
    prev=NULL;
    while (curr!=NULL) {
        next=curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    *head=prev;
}

然后在 main 中,使用reverseDoubleList(&amp;head) 调用它。之后打印列表看看效果。

【讨论】:

    【解决方案2】:

    要创建单个链表的反向副本,一个接一个地复制一个元素并将其添加到反向列表的前面:

    DoubleNode* reverseDoubleListCon( DoubleNode* head) {
        DoubleNode *reverse = NULL;
        while ( head )
        {
            DoubleNode *temp = malloc(sizeof(DoubleNode));
            temp->data = head->data; // copy data to new element
            head = head->next;       // step one forward
            temp->next = reverse;    // successor of new element is first element of reverse list
            reverse = temp;          // head of reverse list is new element
        }
        return reverse;
    }
    
    DoubleNode* reverseHead = reverseDoubleListCon( head );
    

    要反转单个链表,从列表中删除第一个元素并将其添加到反转列表的前面:

     DoubleNode* reverseDoubleList( DoubleNode* head) {
        DoubleNode *reverse = NULL;
        while ( head )
        {
            DoubleNode *temp = head;  // next element is head of list
            head = head->next;        // step one forward
            temp->next = reverse;     // successor of next element is first element of reverse list
            reverse = temp;           // head of reverse list is next element
        }
        return reverse;
    }
    
    head  = reverseDoubleList( head );
    

    【讨论】:

      【解决方案3】:
      void rev(node **head)
      {
          node *prev = NULL;
          node *next = *head->next;
          node *cur;
      
          for (cur = *head; cur; cur = next) {
              next = cur->next;
              prev = cur;
          }
          *head = prev
      }
      

      这是最初的链表:


      第二步:让节点B指向A,让A->next为NULL
      第3步:该过程继续......
      第 4 步:链表现在反转。

      【讨论】:

      • 它不会反转列表。
      • 如何不反转列表? @2501 显然,如果反转列表的代码不起作用,那么它一定不能反转所述列表。错误在哪一行代码上?
      • 整个函数根本就错了。我建议你删除它。
      猜你喜欢
      • 2012-01-30
      • 2016-03-19
      • 2012-10-26
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多