剑指offer---反转链表
问题:反转链表
要求:输入一个链表,反转链表后,输出新链表的表头。
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* ReverseList(ListNode* pHead) { 12 13 } 14 };
对于翻转链表的解法,在博客链表ADT实现中已经完成,只是将其定义为了链表的一种方法,将其代码稍加修改就可以作为此题的解答,代码如下:
1 struct ListNode { 2 int val; 3 struct ListNode *next; 4 ListNode(int x) : 5 val(x), next(NULL) { 6 } 7 }; 8 9 class Solution { 10 public: 11 ListNode* ReverseList(ListNode* pHead) { 12 if (pHead == nullptr || pHead->next == nullptr) 13 return pHead; 14 ListNode *pre = pHead; 15 ListNode *cur = pHead->next; 16 ListNode *temp = pHead->next->next; 17 while (cur){ 18 temp = cur->next; 19 cur->next = pre; 20 pre = cur; 21 cur = temp; 22 } 23 // 末尾元素指针置空 24 pHead->next = nullptr; 25 // 头指针 26 ListNode *newHead = pre; 27 return newHead; 28 } 29 };
代码验证:
若原链表为1(100)->2(200)->3(300),括号中的数字为节点的地址。将原链表反转,则反转之后 head = 300;
以下为验证代码,代码先输出链表,紧接着下一行输出链表每个元素的地址。
1 #include<iostream> 2 using namespace std; 3 4 class Node { 5 public: 6 int data; 7 Node *next; 8 Node(int da): 9 data(da), next(NULL){} 10 }; 11 12 class List{ 13 public: 14 Node *head; 15 List(): head(NULL){} 16 ~List(){ 17 delete head; 18 cout<<"The list is deleted."<<endl; 19 }; 20 int size(); // 链表长度 21 void printList(); // 打印链表 22 void insert(int position, int value); // 指定位置插入 23 void insertHead(int value); // 插入到最前 24 void insertTail(int value); // 插入到最后 25 void reverse(); 26 }; 27 28 // 返回链表大小 29 int List::size(){ 30 Node *p = head; 31 int index = 0; 32 while(p != NULL){ 33 index++; 34 p = p->next; 35 } 36 return index; 37 } 38 39 // 打印链表 40 void List::printList(){ 41 Node *p = head; 42 while(p != NULL){ 43 cout<<p->data<<" "; 44 p = p->next; 45 } 46 cout<<endl; 47 48 p = head; 49 while(p != NULL){ 50 cout<<p<<" "; 51 p = p->next; 52 } 53 cout<<endl<<endl; 54 } 55 56 // 在position位置插入value 57 void List::insert(int position, int value){ 58 if(position<0 || position>List::size()){ 59 cout<<"position error, please check."<<endl; 60 return ; 61 } 62 Node *s = new Node(value); // new node 63 Node *p = head; 64 if(head == NULL){ // isEmpty = true 65 head = s; 66 } 67 else{ // isEmpty = false 68 if(position == 0){ 69 s->next = p; 70 head = s; 71 } 72 else{ 73 int index = 0; 74 while(index != position-1){ 75 p = p->next; 76 index++; 77 } 78 s->next = p->next; 79 p->next = s; 80 } 81 } 82 if (position == 0) 83 cout<<"insert "<<value<<" at the first."<<endl; 84 else if (position == List::size()) 85 cout<<"insert "<<value<<" at the tail."<<endl; 86 else 87 cout<<"insert "<<value<<" at position "<<position<<endl; 88 } 89 90 // 头部插入 91 void List::insertHead(int value){ 92 List::insert(0, value); 93 } 94 95 // 尾部插入 96 void List::insertTail(int value){ 97 List::insert(List::size(), value); 98 } 99 100 // 反转链表 101 void List::reverse(){ 102 if (head == NULL || head->next == NULL) 103 return ; 104 Node *prev = head; 105 Node *cur = head->next; 106 Node *temp = head->next->next; 107 while(cur){ 108 temp = cur->next; 109 cur->next = prev; 110 prev = cur; 111 cur = temp; 112 } 113 head->next = NULL; // 更新末尾元素的指针 114 head = prev; // 更新头结点 115 } 116 117 int main() { 118 List l1; 119 l1.insertTail(6); 120 l1.insertHead(7); 121 l1.insert(1, 5); 122 l1.insert(0, 16); 123 l1.insert(2, 56); 124 l1.insert(0, 169); 125 l1.insert(6, 16); 126 cout<<endl<<"The list is:"<<endl; 127 l1.printList(); 128 l1.reverse(); 129 cout<<endl<<"The reversed list is:"<<endl; 130 l1.printList(); 131 return 0; 132 }
运行结果:
1 insert 6 at the first. 2 insert 7 at the first. 3 insert 5 at position 1 4 insert 16 at the first. 5 insert 56 at position 2 6 insert 169 at the first. 7 insert 16 at position 6 8 9 The list is: 10 169 16 7 56 5 6 16 11 0x661a70 0x661a50 0x661a30 0x661a60 0x661a40 0x661a20 0x661a80 12 13 14 The reversed list is: 15 16 6 5 56 7 16 169 16 0x661a80 0x661a20 0x661a40 0x661a60 0x661a30 0x661a50 0x661a70 17 18 The list is deleted.
可见,地址依次倒序,说明代码正确。