剑指Offer - 九度1518 - 反转链表
2013-11-30 03:09
- 题目描述:
-
输入一个链表,反转链表后,输出链表的所有元素。
(hint : 请务必使用链表)
- 输入:
-
输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000):代表将要输入的链表的个数。
输入的第二行包含n个整数t(0<=t<=1000000):代表链表元素。
- 输出:
-
对应每个测试案例,
以此输出链表反转后的元素,如没有元素则输出NULL。
- 样例输入:
-
5 1 2 3 4 5 0
- 样例输出:
-
5 4 3 2 1 NULL
题意分析:
翻转链表也是经典的链表题了,仔细写都能写出来,不过要严格杜绝new、delete的使用。我曾经喜欢偷懒new一个头节点指向链表头,这样后面反转链表的代码会稍微简化一点。new和delete的问题在于new和delete的操作代价太高,如果函数经常被调用,性能缺陷就会迅速暴露出来。改天要学习一下new和delete的实现机制,明白一次new操作到底有多“贵”。
时间复杂度O(n),空间复杂度O(1)。
1 // 651941 zhuli19901106 1518 Accepted 点击此处查看所有case的执行结果 1024KB 1226B 160MS 2 // 201311152146 3 #include <cstdio> 4 using namespace std; 5 6 struct Node{ 7 int val; 8 struct Node *next; 9 Node(int _val): val(_val), next(NULL){} 10 }; 11 12 Node *reverse_list(Node *head) 13 { 14 Node *root, *tail; 15 16 if(head == NULL){ 17 return NULL; 18 } 19 20 root = new Node(0); 21 while(head != NULL){ 22 tail = head->next; 23 head->next = root->next; 24 root->next = head; 25 head = tail; 26 } 27 head = root->next; 28 delete root; 29 return head; 30 } 31 32 int main() 33 { 34 Node *head, *tail, *root; 35 int i, n, tmp; 36 37 while(scanf("%d", &n) == 1){ 38 if(n <= 0){ 39 printf("NULL "); 40 continue; 41 } 42 root = new Node(0); 43 tail = root; 44 for(i = 0; i < n; ++i){ 45 scanf("%d", &tmp); 46 tail->next = new Node(tmp); 47 tail = tail->next; 48 } 49 head = root->next; 50 head = reverse_list(head); 51 root->next = head; 52 printf("%d", head->val); 53 tail = head->next; 54 while(tail != NULL){ 55 printf(" %d", tail->val); 56 tail = tail->next; 57 } 58 printf(" "); 59 60 tail = root; 61 while(tail != NULL){ 62 head = tail->next; 63 delete tail; 64 tail = head; 65 } 66 } 67 68 return 0; 69 }