如何以相反的顺序打印出单链表?

时间:2016-02-17 07:51:40

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

if-else

截至目前,这打印出来:

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

void *printRev(node *head){
      int count=0;
      int i;
      node *beforeFin;
      node *tempHead;
      tempHead = head;

      while(tempHead->next != NULL){
          count++;
          tempHead->next = tempHead->next->next; //LAST ITERATION SHOULD BE AT THE END OF LIST
      }
      printf("COUNT IS: %d\n", count);
      for(i = 0; i <= count; i++){
        beforeFin = Prev(head, tempHead->next);
        printf("%d", beforeFin->info);
      }
      printf("\n");
    }

COUNT IS: 3 Segmentation fault (core dumped) 在给定指针(Prev)之前返回指向节点的指针,我的意图是使用上面的for循环以相反的顺序打印出单链表。因此,给定节点的tempHead->next应该在下面的示例中返回5(在第一次迭代之后)。

在打印计数的->info之前,printf应指向最终节点。

现在我正在传递tempHead->next这就是给我4点之前的点数。我希望打印出2 3 5 4

我很感激任何帮助,我是初学者,你可能会说。提前谢谢大家!

我可以使用递归来做到这一点,但我想了解这个方法。

3 个答案:

答案 0 :(得分:4)

要以相反的顺序打印单个链接列表,您可以使用递归函数。你必须进入到最后的递归并在离开递归函数之前打印列表的元素:

function searchResult($genre, $subject, $type, $grade){
    if (count(array_filter(func_get_args())) < func_num_args()) {
        echo 'One or many arguments are empty.. do something';
    }
}

如果您不想使用递归,您当然可以反转列表,然后打印列表并最终再次反转。

扭转列表并不困难。遍历列表,获取每个元素并在列表头部前重新排序。

void printReverse(node *act)
{
    if ( act == NULL )          // terminate if end of list is reached
        return;

    printRev( act->next );      // print next node 
    printf( "%d ", act->info ); // print this node
}

答案 1 :(得分:2)

由于您要避免递归,因此需要先反转列表。我在原始代码中看到了一些尝试,但它看起来并不正确。请尝试以下方法:

node *current = head;
if (current != NULL) {
    node *prev = NULL;
    for (node *next = current->next; ; next = (current = next)->next) {
        current->next = prev;
        prev = current;
        if (next == NULL)
            break;
    }
}

然后current将指向列表的头部,您可以使用列表上的next链接进行遍历。请注意,它会修改您的原始列表,但这是我理解的原始要求。

答案 2 :(得分:1)

递归算法的问题在于,如果你像我一样有点偏执,那么列表可能足够大,导致递归调用总结并溢出堆栈。如果列表来自某些用户输入,则可以将其用于拒绝服务攻击。因此,我看到两个合理的选择:

  1. 创建列表的反转副本并打印出来。
  2. 将列表反转到位,打印,然后将其反转。
  3. 如果您在内存受限设置或大型列表中工作,则后者很有趣。

    #include <stdio.h>
    #include <assert.h>
    #include <stdlib.h>
    
    struct node {
      int value;
      struct node * next;
    };
    
    void reverse_inplace (struct node ** list) {
      assert(list != NULL);
      struct node * follow = NULL, * lead = *list;
      while (lead != NULL) {
        struct node * next = lead->next;
        lead->next = follow;
        follow = lead;
        lead = next;
      }
      *list = follow;
    }
    
    void print (struct node const * head) {
      printf("( ");
      while (head) {
        printf("%d ", head->value);
        head = head->next;
      }
      printf(")");
    }
    
    void link (struct node * array, size_t count) {
      struct node * follow = NULL;
      while (count-->0) {
        array[count].next = follow;
        follow = &(array[count]);
      }
    }
    
    void fill (struct node * list, int value, int const step) {
      while (list != NULL) {
        list->value = value;
        value += step;
        list = list->next;
      }
    }
    
    int main () {
      size_t const sizes[] = {1, 2, 6};
      size_t const num =
        sizeof(sizes) / sizeof(sizes[0]);
      size_t caseId = 0;
      for (; caseId < num; ++caseId) {
        struct node * head =
          malloc(sizeof(*head) * sizes[caseId]);
        printf("Case %zu: List of size %zu\n",
          caseId, sizes[caseId]);
        link(head, sizes[caseId]);
        fill(head, caseId, caseId);
        printf("  initial: ");
        print(head);
        printf(" \n");
        reverse_inplace(& head);
        printf(" reversed: ");
        print (head);
        printf(" \n");
        reverse_inplace(& head);
        free(head);
      }
      printf("Case %zu: empty list \n", caseId);
      struct node * head = NULL;
      printf("  initial: ");
      print(head);
      printf(" \n");
      reverse_inplace(& head);
      printf("  reversed: ");
      print(head);
      printf(" \n");
      return 0;
    }
    

    Live on ideone