【演算法題】使用遞迴和非遞迴實現單向連結串列的轉置
在閱讀的過程中有任何問題,歡迎一起交流
QQ:1494713801
問題:
給一個單向連結串列,把它從頭到尾反轉過來。比如: a -> b -> c ->d 反過來就是 d -> c -> b -> a 。
分析:
假設每一個node的結構是:
class Node { char value; Node next;}
非遞迴方式程式碼如下:
1. void reverse(struct Node **list)
2. {
3. struct Node *currentp = *list;
4. struct Node *pleft = NULL;
5. struct Node *pright = NULL;
6.
7.
8. while (currentp != NULL) {
9. pright = currentp->next;
10. currentp->next = pleft;
11. pleft = currentp;
12. currentp = pright;
13. }
14. *list = pleft;
15. }
遞迴的方式程式碼如下:
1. struct Node* recursive_reverse(struct Node *list)
2. {
3. struct Node *head = list;
4. struct Node *p = r_reverse(list);
5. head->next = NULL;
6. return p;
7. }
8.
9. struct Node *r_reverse(struct Node *list)
10. {
11. if (NULL == list || NULL == list->next)
12. return list;
13. struct Node *p = r_reverse(list->next);
14. list->next->next = list;
15. return p;
16. }
遞迴的方法其實是非常巧的,它利用遞迴走到連結串列的末端,然後再更新每一個node的next 值 (程式碼倒數第二句)。 在上面的程式碼中, reverseRest 的值沒有改變,為該連結串列的最後一個node,所以,反轉後,我們可以得到新連結串列的head。
單鏈表相鄰元素轉置(非遞迴)
1. struct Node* recursive_reverse(struct Node *list)
2. {
3. struct Node *head = list;
4. struct Node *p = r_reverse(list);
5. head->next = NULL;
6. return p;
7. }
8.
9. struct Node *r_reverse(struct Node *list)
10. {
11. if (NULL == list || NULL == list->next)
12. return list;
13. struct Node *p = r_reverse(list->next);
14. list->next->next = list;
15. return p;
16. }
4 單鏈表相鄰元素轉置(遞迴)
1. struct Node * recursive_partial_reverse(struct Node *list)
2. {
3. if (NULL == list || NULL == list->next)
4. return list;
5. struct Node *p = list->next;
6. struct Node *node = recursive_partial_reverse(list->next->next);
7. list->next->next = list;
8. list->next = node;
9. return p;
10. }
參考連結:
http://blog.csdn.net/skylinesky/article/details/760694