所谓链表逆序,是把诸如 1->2->3->4->null 的链表变换为 4->3->2-1->null。假设链表节点定义如下:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
解法一:
新建临时节点tmp_head,遍历原始链表,将原始链表头插入tmp_head之后,最后返回tmp_head。如是则返回了逆序后的链表。
ListNode * reverseList(ListNode *head)
{
if (head == NULL || head->next == NULL)
return head;
ListNode *tmp_head, *next;
tmp_head = new ListNode(-1); //create a temporary head Node, notice that tmp_head->next is NULL
next = head->next;
while (head != NULL){
next = head->next;
head->next = tmp_head->next;
tmp_head->next = head;
head = next;
}
head = tmp_head->next;
delete tmp_head; //free the temporary head Node
return head;
}
解法二:
利用三个指针p、q、n,三个指针初试时如下图所示:
然后变换指针:
然后将p、q、n向后挪动一个位置:
如是反复,直到n的值为空,此时链表如下图所示:
程序代码如下:
ListNode * reverseList(ListNode *head)
{
if (head == NULL || head->next == NULL)
return head;
ListNode *p, *q, *n;
p = head, q = p->next, n = q->next;
p->next = NULL;//notice that initially we should set the next filed of the first node to NULL
while (n != NULL) {
q->next = p;
p = q; q = n;
n = n->next;
}
q->next = p;
head = q;
return head;
}
接下来是两种递归实现。但链表的处理不宜使用递归,因为当链表过长的时候,容易导致栈溢出。
解法三:
ListNode * recursiveReverseList(ListNode *p, ListNode *last)
{
if (p->next == NULL){
p->next = last;
return p;
}
ListNode *tmp = p->next;
p->next = last;
return recursiveReverseList(tmp, p);
}
ListNode * reverseList(ListNode *head)
{
if (head == NULL || head->next == NULL)
return head;
return recursiveReverseList(head, NULL);
}
解法四:
ListNode * recursiveReverseList(ListNode *p)
{
if (p->next == NULL)
return p;
ListNode *new_head = recursiveReverseList(p->next);
p->next->next = p;
return new_head;
}
ListNode * reverseList(ListNode *head)
{
if (head == NULL || head->next == NULL)
return head;
ListNode *new_head = recursiveReverseList(head);
head->next = NULL;
return new_head;
}
由上可见,解法三和解法四并没有本质的不同。但相对而言,无论是函数递归调用还是代码结构,解法三更好一些。下述代码是我测试以上函数时用到的代码。建议通过如下命令编译程序:
g++ filename.cpp -std=c++11
ListNode * reverseList(ListNode *head)
{
return NULL;
}
ListNode * genList()
{
vector<int> data = {1, 2, 3, 4};
ListNode * head, *tmp;
head = tmp = new ListNode(0);
for (int j = 0; j < data.size(); ++j){
tmp->next = new ListNode(data[j]);
tmp = tmp->next;
}
tmp->next = NULL;
tmp = head->next;
delete head;
return tmp;
}
void print_list(ListNode *head)
{
cout << "print_list :" << endl;
if (head == NULL){
cout << endl;
return;
}
ListNode *tmp = head;
while(tmp != NULL){
cout << tmp->val << " ";
tmp = tmp->next;
}
cout << endl;
}
int main()
{
ListNode * head = genList();
print_list(head);
head = reverseList(head);
print_list(head);
head = reverseList(head);
print_list(head);
return 0;
}