我应该颠倒链接列表的顺序,我认为我有正确的想法,但由于某种原因,当我打印出列表并且我不确定时,我的代码进入无限循环为什么我认为它与最后的for循环有关,因为当我评论那部分并再次测试它时,再也没有无限循环了。
这是列表的示例:
42, 36, 14, 17, 48, 36
这就是我想要得到的:
36, 48, 17, 14, 36, 42
以下是我的代码:
// 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;
}
}
答案 0 :(得分:3)
你在for循环中编写的代码是错误的。
为了给你一个想法让我们举个例子。最初您的清单是
42 -> 36 -> 14 -> 17 -> 48 -> 36
| |
ELEhead ELEtail
就在for循环之前:ELEtail指向36(最后一个元素),ELEhead指向42(第一个元素)。
现在,在for循环的第一次迭代之后:ELEtail指向42,ELEhead指向36(初始列表的第二个元素),列表变为
42 -> 36 -> 14 -> 17 -> 48 -> 36 -> 42
| |
ELEhead ELEtail
上面示例中的第一个和最后一个42是相同的元素。因此它会产生无限循环。
现在要反转链接列表,只需要一个指针来反转链接列表的头部。每当您在原始链接列表中遇到新元素时,只需在反向链接列表的头部输入它即可。当您在新链接列表的头部插入原始链接列表的最后一个元素时,您的链接列表将被反转。为此你甚至不需要知道原始列表的长度。这将保存您计算链表长度的第一个循环。
答案 1 :(得分:0)
尝试此操作,您无需知道列表或循环的大小。
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;
}