分析
单链表倒置有两种方式,一种是压栈递归的方式,一种是头插法循环的方式。
递归法:
先把所有元素依次压栈,然后再出栈,依次指向下一个。考虑采用递归的方法,依次压栈即依次递归调用reserveList(head->next)函数,直到head为最后一个元素停止压栈,返回最后一个元素。然后依次出栈。
代码如下:
ListNode* reserveList1(ListNode* head) {
ListNode* newhead, *pre;
if(head->next == NULL){
return head;
}
newhead = reserveList1(head->next);
pre = head->next;
pre->next = head;
head->next = NULL;
return newhead;
}
非递归法:
依次头插,next指针指向还未倒置的链表的首个节点,head指针指向已倒置链表的首节点并逐渐加入新节点,pre记录下已倒置链表的首节点作为下一次循环head节点的next。
ListNode* reserveList2(ListNode* head) {
ListNode* next = NULL;
ListNode* pre = NULL;
while(NULL != head) {
next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
代码汇总
#include <iostream>
using namespace std;
struct ListNode{
ListNode* next;
int val;
};
ListNode* init(int a[], int n) {
ListNode *head = NULL, *last = NULL;
for(int i= 0; i < n; i++) {
ListNode* node = new ListNode;
node->val = a[i];
if(i == 0) {
head = node;
last = node;
}
else {
last->next = node;
last = node;
}
if(i == n-1) {
node->next = NULL;
}
}
return head;
}
ListNode* reserveList1(ListNode* head) {
ListNode* newhead, *pre;
if(head->next == NULL){
return head;
}
newhead = reserveList1(head->next);
pre = head->next;
pre->next = head;
head->next = NULL;
return newhead;
}
ListNode* reserveList2(ListNode* head) {
ListNode* next = NULL;
ListNode* pre = NULL;
while(NULL != head) {
next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
void printList(ListNode* head, int n){
ListNode* node = head;
while (n > 0) {
cout << node->val << " ";
node = node->next;
n--;
}
cout << "end" << endl;
}
int main() {
int a[] = {1,2,3,4,5,6};
int size = sizeof(a)/ sizeof(int);
ListNode* head = init(a, size);
printList(head, size);
ListNode* newhead = reserveList1(head);
printList(newhead, size);
ListNode* newhead2 = reserveList2(newhead);
printList(newhead2, size);
return 0;
}
结果