題目描述:
-
輸入一個鏈表,反轉鏈表后,輸出鏈表的所有元素。
(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
解題思路:
我們考慮到,如果是想通過題目AC,可以直接以頭插的方式一次輸入數據,輸出數據既是倒轉數據。但是面試題目本意並非如此,那么如果是一個現有的鏈表逆轉,卻又不用太高的時間復雜度,和空間復雜度呢。有一種想法,既然我們一次遍歷鏈表,那么直接改變鏈表指針不就行了?
思路大致如此:
首先,考慮到一般情況,我們翻轉指針,每次利用指針p和p->next也就是p1來改變p1元素的位置,代碼如下:
Node *p = head->next; Node *p1 = p->next; while(p->next != NULL){ p->next = p1->next; p1->next = head->next; head->next = p1; p1 = p->next; }
但是考慮到特殊情況
1 如果鏈表為空,那么根本不需要處理
if(head->next == NULL) return 0;
2 如果鏈表只有一個元素,那么根本不需要倒轉
if(head->next->next == NULL) return 1;
代碼:
#include <stdio.h> #include <stdlib.h> typedef struct node{ int number; struct node * next; }Node; int reverseList(Node * head); int main(){ int n,i; while(scanf("%d",&n)!=EOF && n>=0 && n <= 1000){ Node *head = (Node *)malloc(sizeof(Node)); head->next = NULL; Node *tail = head; for(i=0;i<n;i++){ int temp; scanf("%d",&temp); Node *p = (Node *)malloc(sizeof(Node)); p->next = tail->next; p->number = temp; tail->next = p; tail = tail->next; } int flag = reverseList(head); if(flag){ Node *p = head->next; while(p->next != NULL){ printf("%d ",p->number); p = p->next; } printf("%d\n",p->number); } else printf("NULL\n"); } return 0; } int reverseList(Node * head){ if(head->next == NULL) return 0; if(head->next->next == NULL) return 1; Node *p = head->next; Node *p1 = p->next; while(p->next != NULL){ p->next = p1->next; p1->next = head->next; head->next = p1; p1 = p->next; } return 1; } /************************************************************** Problem: 1518 User: xhalo Language: C Result: Accepted Time:150 ms Memory:2364 kb ****************************************************************/