【转】单向链表的反转问题
【转载】http://www.cnblogs.com/wyqx/p/3346293.html
这次介绍经常在面试中被问到的单向链表的反转问题,问题的解决方法有多种
- 最普通的是从头到尾扫描链表,然后对链表进行反转。
- 使用单个参数的递归方法;使用单个参数是相当于不断的往链表后部深入,并且在每次深入的递归中保存了下一个节点和当前节点的信息,再调用递归后处理当前节点和下一个节点的关系;其中比较有特点的处理过程是返回值的处理,每次递归后返回的指针为同一个;
- 使用两个参数的递归方法,外加一个当前链表头节点的前一个结点的指针,在进一步递归之前处理好头节点和其前一个节点的关系。
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 struct Node{ 5 int value; 6 Node* next; 7 }; 8 9 //使用非递归的链表反转方法 10 Node* ReverseList1(Node *Ptr) 11 { 12 Node *pre = NULL; 13 Node *Current = Ptr; 14 Node *pnext = NULL; 15 while ( Current != NULL){ 16 pnext = Current->next; 17 Current->next = pre; 18 pre = Current; 19 Current = pnext; 20 } 21 return pre; 22 } 23 // 一个参数的递归反转方法 24 // 将当前节点的下一个节点保存好,并将当前节点从链表中取出,再递归处理以后的链表 25 // 同时reverseRest没有改变,一直保存了链表的最后一个节点的指针 26 Node* ReverseList2(Node *ptr){ 27 if (ptr->next == NULL) 28 return ptr; 29 Node *nextNode = ptr-> next; 30 ptr->next = NULL; 31 Node *reverseRest = ReverseList2(nextNode); 32 nextNode->next = ptr; 33 return reverseRest; 34 35 36 } 37 38 // 递归实现2:两个参数的递归调用方法 39 // 传递一个当前链表头节点的前一个节点的指针,在函数中将当前头节点的next改为其前一个节点,并递归调用 40 Node* ReverseList3(Node *ptr, Node *pre){ 41 if (ptr->next == NULL){ 42 ptr->next = pre; 43 return ptr; 44 } 45 else{ 46 Node *next = ptr->next; 47 ptr->next = pre; 48 ReverseList3(next, ptr); 49 } 50 } 51 52 53 void printList(Node *Ptr){ 54 Node * Current = Ptr; 55 while (Current != NULL){ 56 cout << Current->value << " "; 57 Current = Current->next; 58 } 59 cout << endl; 60 } 61 62 int main(){ 63 Node *head = NULL; 64 65 for (int i = 9; i > 0; i--){ 66 Node *p = new Node; 67 p->next = head; 68 p->value = i; 69 head = p; 70 } 71 cout << "The Lsit:" << endl; 72 printList(head); 73 74 head = ReverseList1(head); 75 cout << "After reverseList1():" << endl; 76 printList(head); 77 78 79 head = ReverseList2(head); 80 cout << "After reverseList2():" << endl; 81 printList(head); 82 83 Node * tmp = NULL; 84 head = ReverseList3(head, tmp); 85 cout << "After reverseList3():" << endl; 86 printList(head); 87 88 return 1; 89 90 }