转载请注明出处:http://blog.csdn.net/ns_code/article/details/25028525
剑指offer上的第五题,在九度OJ上测试通过。
-
题目描述:
-
输入一个链表,从尾到头打印链表每个节点的值。
-
输入:
-
每个输入文件仅包含一组测试样例。
每一组测试案例包含多行,每行一个大于0的整数,代表一个链表的节点。第一行是链表第一个节点的值,依次类推。当输入到-1时代表链表输入完毕。-1本身不属于链表。
-
输出:
-
对应每个测试案例,以从尾到头的顺序输出链表每个节点的值,每个值占一行。
-
样例输入:
-
1 2 3 4 5 -1
-
样例输出:
-
5 4 3 2 1
AC代码如下:
- #include<stdio.h>
- #include<stdlib.h>
- typedef int ElemType;
- typedef struct Node
- {
- ElemType data;
- struct Node *next;
- }Node,*pNode;
- /*
- 递归从尾到头打印单链表
- */
- void PrintListReverse(pNode pHead)
- {
- if(pHead == NULL)
- return;
- if(pHead->next != NULL)
- PrintListReverse(pHead->next);
- printf("%d\n",pHead->data);
- }
- pNode CreateList()
- {
- ElemType val;
- pNode pHead = NULL;
- pNode pCur = NULL;
- do
- {
- scanf("%d",&val);
- if(val != -1)
- {
- pNode pNew = (pNode)malloc(sizeof(Node));
- if(pNew == NULL)
- exit(EXIT_FAILURE);
- pNew->data = val;
- pNew->next = NULL;
- if(pHead == NULL)
- {
- pHead = pNew;
- pCur = pHead;
- }
- else
- {
- pCur->next = pNew;
- pCur = pCur->next;
- }
- }
- }while(val != -1);
- return pHead;
- }
- void DestroyList(pNode pHead)
- {
- if(pHead == NULL)
- return;
- pNode p = NULL;
- while(pHead != NULL)
- {
- p = pHead->next;
- free(pHead);
- pHead = p;
- }
- }
- int main()
- {
- pNode pHead = CreateList();
- PrintListReverse(pHead);
- DestroyList(pHead);
- return 0;
- }
/**************************************************************
Problem: 1511
User: mmc_maodun
Language: C
Result: Accepted
Time:100 ms
Memory:5440 kb
****************************************************************/
以上为递归方式。
四种方式实现--从尾到头输出链表
方法一:借用栈倒序输出链表
方法二:先翻转链表,再顺序输出
方法三:递归实现,一个字妙,两个字很妙,三个字太妙了
方法四:用数组实现
方法一:借用栈倒序输出链表
因为栈是先进后出,把链表中的元素存进栈中,链表前面的元素在栈底,后面的元素在栈顶,链表后面的元素先出栈
方法二:先翻转链表,再按顺序打印(主要是想自己实现单链表的翻转,这种实现方式破坏了链表的结构,当然再翻转一下就还原了)
翻转链表的步骤:
1:将当前节点的next节点指向他以前的前一个节点
2:当前节点下移一位
3:如果是最后一个节点,就把它的next节点指向它以前的前一个节点,并推出循环
方法三:用递归实现
很诚实的说盗用了别人的思想,真的太妙了,完全能看出你是否真的体会了递归的原理
正如那位哥们所说,递归就是一个进栈出栈的过程,链表前面的元素先进栈,在栈底,后面的元素后进栈,在栈顶,先出栈,哈哈。。。
方法四:借用数组实现,跟用栈实现的方式差不多, LoveJenny说的实现方式跟这种方式是一样的,空间复杂度都是O(n)