简体   繁体   English

在C中反转链接列表

[英]Reversing a Linked List in C

I am supposed to reverse the order of a linked list, and I think I got the right idea, but for some reason, my code is entering an infinite loop when I print out the list and I'm not sure why I think it has something to do with the for loop near the end, because when I comment that part out and test it again, there's no infinite loop anymore. 我应该颠倒链表的顺序,我认为我有正确的想法,但由于某种原因,当我打印出列表时,我的代码进入无限循环,我不知道为什么我认为它有与接近结尾的for循环有关,因为当我评论该部分并再次测试它时,不再有无限循环了。

This is an example of what a list might look like: 这是列表的外观示例:

42, 36, 14, 17, 48, 36

And this is what I'm trying to get: 这就是我想要得到的:

36, 48, 17, 14, 36, 42

And below is my code: 以下是我的代码:

// List element: a list is a chain of these
typedef struct element
{
  int val;
  struct element* next;
} element_t;

// List header - keep track of the first and last list elements
typedef struct list
{
  element_t* head;
  element_t* tail;
} list_t;



void reverse (list_t* L)
{
  //getting the len of the list
  unsigned int len = 0;
  element_t* temp = L->head;
  while (temp != L->tail)
  {
    len++;
    temp = temp->next;
  }
  len++; //extra +1 len for tail since while loop does not include


  //now for reversing 
  unsigned int i = 0;
  element_t* ELEtail = L->tail;
  element_t* ELEhead = L->head;
  for (i = 0; i < len-1; i++)
  {
    ELEtail->next = ELEhead;
    ELEhead = ELEhead->next;
    ELEtail = ELEtail->next;
  }

}

The code you write in your for loop is wrong. 你在for循环中编写的代码是错误的。

To give you an idea let us take your example. 为了给你一个想法让我们举个例子。 Initially your list is 最初你的清单是

42 -> 36 -> 14 -> 17 -> 48 -> 36
|                             |
ELEhead                    ELEtail

Just before the for loop: ELEtail points to 36 (last element) and ELEhead points to 42 (first element). 就在for循环之前:ELEtail指向36(最后一个元素),ELEhead指向42(第一个元素)。

Now after the first iteration of your for loop : ELEtail points to 42 and ELEhead points to 36(second element of initial list) and the list becomes 现在,在for循环的第一次迭代之后:ELEtail指向42并且ELEhead指向36(初始列表的第二个元素)并且列表变为

42 -> 36 -> 14 -> 17 -> 48 -> 36 -> 42
 |                                   |
ELEhead                           ELEtail

First and the last 42 in above example are same element. 上面示例中的第一个和最后一个42是相同的元素。 Hence it makes an infinite loop. 因此它会产生无限循环。

Now to reverse the link list, you require only one pointer for the head of the reversed linklist. 现在要反转链接列表,只需要一个指针来反转链接列表的头部。 Every time you encounter a new element in the original linklist just enter it at the head of the reversed linklist. 每当您在原始链接列表中遇到新元素时,只需在反向链接列表的头部输入它即可。 And your linklist will be reversed when you insert the last element of original linklist at the head of the new linklist. 当您在新链接列表的头部插入原始链接列表的最后一个元素时,您的链接列表将被反转。 And for that you don't even require to know the length of the original list. 为此你甚至不需要知道原始列表的长度。 This will save your first loop where you are calculating the length of the linklist. 这将保存您计算链表长度的第一个循环。

Try this on, you don't need to know the size of your list or loop. 试试这个,您不需要知道列表或循环的大小。

void reverse_list(list_t* l) {
    element_t* new_tail = l->head;
    element_t* new_head = reverse(l->head); //Assumes l isn't NULL!
    l->head = new_head;
    l->tail = new_tail;        
}

element_t* reverse(element_t* head) {
    if(list == NULL)
        return NULL;
    if (list->next == NULL)
        return head;
    element_t* body = reverse(head->next);
    head->link->link = head; // reverse head
    head->link = NULL;
    return body;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM