只用一个额外的节点实现单链表的反转
testcase如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct num {
int data;
struct num *next;
} *num_ptr;
void print_num(num_ptr head) {
num_ptr tmp = head;
while (tmp->next) {
printf("%d\n", tmp->next->data);
tmp = tmp->next;
}
printf("\n");
}
num_ptr reverse_link(num_ptr head) {
num_ptr priv = head->next;
num_ptr cur = head->next->next;
num_ptr tmp = (num_ptr)malloc(sizeof(struct num));
tmp->next = cur->next;
priv->next = NULL;
while (cur->next) {
// start reverse
cur->next = priv;
// priv change to next
priv = cur;
// cur change to next, this is why need tmp node
cur = tmp->next;
// tmp still save cur next
tmp->next = cur->next;
}
// change last node next null to priv
cur->next = priv;
head->next = cur;
return head;
}
int main()
{
num_ptr head, one, two, three, four;
head = (num_ptr)malloc(sizeof(struct num));
one = (num_ptr)malloc(sizeof(struct num));
two = (num_ptr)malloc(sizeof(struct num));
three = (num_ptr)malloc(sizeof(struct num));
four = (num_ptr)malloc(sizeof(struct num));
one->data = 1;
two->data = 2;
three->data = 3;
four->data = 4;
head->next = one;
one->next = two;
two->next = three;
three->next = four;
four->next = NULL;
print_num(head);
num_ptr new_head = reverse_link(head);
print_num(new_head);
return 0;
}
这个问题的关键就在于那一个额外的节点,因为当链表做完反转之后就无法指向链表的下一个节点了,这个时候用额外的节点去记住反转的节点的下一个节点,这样子就可以继续进行下一轮反转了