题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。

链表结点定义如下:

Struct ListNode{

int   m_nKey;

ListNode*   m_pNext;

};

  

我们可以用栈来实现“后进先出”的顺序。每经过一个结点的时候,把该结点防到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。

  1. void PrintListReversingly_Iteratively(ListNode* pHead){
  2.   std::stack<ListNode*> node;
  3.   ListNode* pNode = pHead;
  4.   while(pNode != null){
  5.     nodes.push(pNode);
  6.     pNode = pNode->m_pNext;
  7. }
  8.   while(!nodes.empty()){
  9.     pNode = nodes.top();
  10.     printf("%d\t",pNode->m_nValue);
  11.     nodes.pop();
  12.   }
  13. }

  我们也可以用递归来实现反过来输出链表,我们每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身,这样链表的输出结果就反过来了。

  1. void PrintListReversingly_Recursively(ListNode* pHead){
  2.   if(pHead != null){
  3.     if(pHead->m_pNext != null){
  4.        PrintListReversingly_Recursively(pHead->m_pNext);
  5.     }
  6.     printf("%d\t",pHead->m_nValue);
  7.   } 
  8. }

java精简版:

Node类:

  1. package com.yyq;
  2.  
  3. /**
  4. * Created by Administrator on 2015/9/8.
  5. */
  6. public class Node {
  7. String value;
  8. Node next;
  9. public Node(String value){
  10. this.value = value;
  11. }
  12.  
  13. public String getValue() {
  14. return value;
  15. }
  16.  
  17. public Node getNext() {
  18. return next;
  19. }
  20.  
  21. public void setNext(Node next) {
  22. this.next = next;
  23. }
  24.  
  25. public void setValue(String value) {
  26. this.value = value;
  27. }
  28. };

处理类:

  1. package com.yyq;
  2. import java.util.Stack;
  3.  
  4. /**
  5. * Created by Administrator on 2015/9/8.
  6. */
  7. public class PrintLinkReversingly {
  8. public static void main(String[] args) {
  9. Node a = new Node("A");
  10. Node b = new Node("B");
  11. Node c = new Node("C");
  12. Node d = new Node("D");
  13. Node e = new Node("E");
  14. Node f = new Node("F");
  15. Node g = new Node("G");
  16. a.next = b;
  17. b.next = c;
  18. c.next = d;
  19. d.next = e;
  20. e.next = f;
  21. f.next = g;
  22. printTailToStartRec(a);
  23. printTailToStartStack(a);
  24. }
  25.  
  26. public static void printTailToStartRec(Node start) {
  27. if (start == null ) return;
  28. if (start.next!= null) {
  29. printTailToStartRec(start.next);
  30. }
  31. System.out.println(start.value);
  32. }
  33.  
  34. private static void printTailToStartStack(Node node) {
  35. if (node == null) {
  36. System.out.println("list is null");
  37. return;
  38. }
  39.  
  40. Stack<Node> stack = new Stack<Node>();
  41. while (node != null) {
  42. stack.push(node);
  43. node = node.next;
  44. }
  45. while (!stack.isEmpty()) {
  46. System.out.println(stack.pop().value);
  47. }
  48. }
  49. }

输出结果:

F

E

D

C

B

A

G

F

E

D

C

B

A

Process finished with exit code 0

java版本:

链表接口定义:

  1. package com.yyq;
  2.  
  3. /**
  4. * Created by Administrator on 2015/9/4.
  5. */
  6. public interface Link {
  7. //向链表增加数据
  8. void add(Object data);
  9.  
  10. //可以增加一组对象
  11. void add(Object data[]);
  12.  
  13. //在链表中删除数据
  14. void delete(Object data);
  15.  
  16. //判断数据是否存在
  17. boolean exists(Object data);
  18.  
  19. //取得全部的保存对象
  20. Object[] getAll();
  21.  
  22. //根据保存的位置取出指定对象
  23. Object get(int index);
  24.  
  25. //求出链表的长度
  26. int length();
  27. }

链表类定义:

  1. package com.yyq;
  2.  
  3. /**
  4. * Created by Administrator on 2015/9/4.
  5. */
  6. public class LinkImpl implements Link {
  7. class Node {
  8. private Object data;
  9. private Node next;
  10.  
  11. public Node(Object data) {
  12. this.data = data;
  13. }
  14.  
  15. public void addNode(Node newNode) {
  16. if (this.next == null) {
  17. this.next = newNode;
  18. } else {
  19. this.next.addNode(newNode);
  20. }
  21. }
  22.  
  23. public void deleteNode(Node previous, Object data) {
  24. if (this.data.equals(data)) {
  25. previous.next = this.next;
  26. } else {
  27. if (this.next != null) {
  28. this.next.deleteNode(this, data);
  29. }
  30. }
  31. }
  32.  
  33. public void getAll() {
  34. retdata[foot++] = this.data; //取出当前节点中的数据
  35. if (this.next != null) {
  36. this.next.getAll();
  37. }
  38. }
  39. };
  40. private int foot = 0;
  41. private Node root; //根节点
  42. private int len;
  43. private Object retdata[];//接收全部的返回值数据
  44.  
  45. //向链表增加数据
  46. @Override
  47. public void add(Object data) {
  48. if (data != null) {
  49. len++; //保存个数
  50. Node newNode = new Node(data);
  51. if (this.root == null) {
  52. this.root = newNode;
  53. } else {
  54. this.root.addNode(newNode);
  55. }
  56. }
  57. }
  58.  
  59. //可以增加一组对象
  60. @Override
  61. public void add(Object data[]) {
  62. for(int x = 0; x < data.length; x++){
  63. this.add(data[x]);
  64. }
  65. }
  66.  
  67. //在链表中删除数据
  68. @Override
  69. public void delete(Object data) {
  70. if(this.exists(data)){//如果存在,则执行删除
  71. if(this.root.equals(data)){
  72. this.root = this.root.next;
  73. }else {
  74. this.root.next.deleteNode(this.root,data);
  75. }
  76. }
  77. }
  78.  
  79. //判断数据是否存在
  80. @Override
  81. public boolean exists(Object data) {
  82. if(data == null){
  83. return false;
  84. }
  85. if(this.root == null){
  86. return false;
  87. }
  88. Object d[] = this.getAll();//取得全部的数据
  89. boolean flag = false;
  90. for(int x = 0; x < d.length; x++){
  91. if(data.equals(d[x])){
  92. flag = true;
  93. break;
  94. }
  95. }
  96. return flag;
  97. }
  98.  
  99. //取得全部的保存对象
  100. @Override
  101. public Object[] getAll() {
  102. this.foot = 0;
  103. if(this.len != 0){
  104. this.retdata = new Object[this.len];//根据大小开辟数组
  105. this.root.getAll();
  106. return this.retdata;
  107. }else{
  108. return null;
  109. }
  110. }
  111.  
  112. //根据保存的位置取出指定对象
  113. @Override
  114. public Object get(int index) {
  115. Object d[] = this.getAll();
  116. if(index < d.length){
  117. return d[index];
  118. }else{
  119. return null;
  120. }
  121. }
  122.  
  123. //求出链表的长度
  124. @Override
  125. public int length() {
  126. return this.len;
  127. }
  128. }

链表使用举例:

  1. package com.yyq;
  2.  
  3. /**
  4. * Created by Administrator on 2015/9/4.
  5. */
  6. public class PrintListReversingly {
  7. public static void main(String[] args) {
  8.  
  9. Link link = new LinkImpl();
  10. link.add("A");
  11. link.add("B");
  12. link.add("C");
  13. link.add(new String[]{"X","Y"});
  14. Object obj[] = link.getAll();
  15. for(Object o : obj){
  16. System.out.println(o);
  17. }
  18. System.out.println(obj.length);
  19. System.out.println(link.exists(null));
  20. System.out.println(link.get(3));
  21. link.delete("X");
  22. obj = link.getAll();
  23. for(Object o : obj){
  24. System.out.println(o);
  25. }
  26. System.out.println(obj.length); //注意这里还是原来obj开辟时的长度
  27. }
  28. }

从尾到头打印链表:

  1. package com.yyq;
  2.  
  3. import java.util.Stack;
  4.  
  5. /**
  6. * Created by Administrator on 2015/9/4.
  7. */
  8. public class PrintListReversingly {
  9. public static void main(String[] args) {
  10. Link link = new LinkImpl();
  11. link.add("A");
  12. link.add("B");
  13. link.add("C");
  14. link.add(new String[]{"D","E","F","G"});
  15. Object obj[] = link.getAll();
  16. for(Object o : obj){
  17. System.out.println(o);
  18. }
  19.  
  20. int len = obj.length;
  21. System.out.println("============");
  22. for(int i = len-1; i >= 0; i--){
  23. System.out.println(obj[i]);
  24. }
  25.  
  26. }
  27. }

P51、面试题5:从尾到头打印链表的更多相关文章

  1. 【剑指offer】面试题 6. 从尾到头打印链表

    面试题 6. 从尾到头打印链表 NowCoder 题目描述 输入一个链表的头结点,从尾到头反过来打印出每个结点的值. Java 实现 ListNode Class class ListNode { i ...

  2. 剑指offer-面试题5.从尾到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 刚看到这道题的小伙伴可能就会想,这还不简单,将链表反转输出. 但是这种情况破坏了链表的结构. 如果面试官要求不破坏链表结构呢,这时候我们 ...

  3. 前端常见算法面试题之 - 从尾到头打印链表[JavaScript解法]

    题目描述 输入一个链表的头结点,从尾到头反过来打印出每个结点的值 实现思路 前端工程师看到这个题目,直接想到的就是,写个while循环来遍历链表,在循环中把节点的值存储在数组中,最后在把数组倒序后,遍 ...

  4. 剑指offer_面试题5_从尾到头打印链表(栈和递归实现)

    题目:输入一个链表的头结点,从尾到头反过来打印出每一个节点的值 考察 单链表操作.栈.递归等概念. 理解:要实现单链表的输出,那么就须要遍历.遍历的顺序是从头到尾.而节点输出的顺序是从尾到头.因此,先 ...

  5. 《剑指offer》面试题5—从尾到头打印链表

    重要思路: 这个问题肯定要遍历链表,遍历链表的顺序是从头到尾,而要输出的顺序却是从尾到头,典型的“后进先出”,可以用栈实现. 注意stl栈的使用,遍历stack的方法. #include <io ...

  6. 【剑指Offer】面试题06.从尾到头打印链表

    题目 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 1000 ...

  7. 《剑指offer》面试题06. 从尾到头打印链表

    问题描述 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10 ...

  8. 剑指Offer:面试题5——从尾到头打印链表(java实现)

    问题描述:输入一个链表的头结点,从尾巴到头反过来打印出每个结点的值. 首先定义链表结点 public class ListNode { int val; ListNode next = null; L ...

  9. 《剑指offer》面试题5 从尾到头打印链表 Java版

    书中方法一:反转应该立刻想到栈,利用一个栈完成链表的反转打印,但是用了额外的O(n)空间. public void printFromTail(ListNode first){ Stack<Li ...

随机推荐

  1. (五)Qt5之中文显示

    Qt中的中文显示,经常会出现乱码,但在UI设计界面上添加的中文是不会出现乱码的,如果你刚使用qt,那么你肯定会碰到这个问题. 网上搜索一下,找到的都是这种: #include < QTextCo ...

  2. Word中批量替换软回车

    在平时工作中,有时候需要拷贝一些截取自网页上的文字,当选中后拷贝到Word中时,有时候在每行的结尾出现如下的符号,,这给后期文字的整理带来了很多不便,在此记录从网上获取的解决方法,以免遗忘和便于查找. ...

  3. Building microservices with Spring Cloud and Netflix OSS, part 2

    In Part 1 we used core components in Spring Cloud and Netflix OSS, i.e. Eureka, Ribbon and Zuul, to ...

  4. Objective-C中class、Category、Block的介绍

    @class 当定义一个类,必须为编译器提供两组消息,第一组(接口部分.h):构建类的实例的一个基本蓝图.必须指定类名,类的超类,类的实例变量和类型的列表,最后是类的方法的声明.第二组(实现部分.m) ...

  5. Spark Streaming揭秘 Day26 JobGenerator源码图解

    Spark Streaming揭秘 Day26 JobGenerator源码图解 今天主要解析一下JobGenerator,它相当于一个转换器,和机器学习的pipeline比较类似,因为最终运行在Sp ...

  6. Linux进程间通信IPC学习笔记之管道

    基础知识: 管道是最初的Unix IPC形式,可追溯到1973年的Unix第3版.使用其应注意两点: 1)没有名字: 2)用于共同祖先间的进程通信: 3)读写操作用read和write函数 #incl ...

  7. 在iframe结构中,如何使弹出层位于所有框架的上方(-)

    在做后台管理页面的时候,经常用到iframe.虽说这东西有些过时,也不利于SEO,但是后台就是后台,不需要考虑那么多东西,综合来说,用iframe还是很适合后台管理界面的. 但是在遇到弹出层时,出现了 ...

  8. win 7 64位如何安装erdas 9.2

    最主要的就是crack包必须包含这三个文件:erdas.exe、license.dat和lmgrd.exe 将这三个文件都复制到C盘安装目录下bin中,其余安装同win 7 32位系统

  9. XSS前端防火墙

    前一段时间,在EtherDream大神的博客里看到关于XSS防火墙的一系列文章,觉得很有意思.刚好科创要做一个防火墙,就把XSS前端防火墙作为一个创新点,着手去实现了. 在实现过程中,由于各种原因,比 ...

  10. div蒙版+可移动

    <html> <head>     <title></title>     <script src="jquery-1.8.2.js&q ...