一、题目:从尾到头打印链表

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

  到解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后进先出”,我们可以用栈实现这种顺序。

二、解题思路

  每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。

三、解决问题

3.1 代码实现

  这里使用的是自定义实现的链表类,其节点定义如下:

    public class Node<T>
{
// 数据域
public T Item { get; set; }
// 指针域
public Node<T> Next { get; set; } public Node()
{
} public Node(T item)
{
this.Item = item;
}
}

  这里的自定义的单链表的实现请参考:《数据结构基础温故-1.线性表(中)

  (1)基于栈的循环版本

    public static void PrintListReversinglyIteratively(Node<int> head)
{
Stack<Node<int>> stackNodes = new Stack<Node<int>>();
Node<int> node = head;
// 单链表元素依次入栈
while (node != null)
{
stackNodes.Push(node);
node = node.Next;
}
// 栈中的单链表元素依次出栈
while (stackNodes.Count > )
{
Node<int> top = stackNodes.Pop();
Console.Write("{0}", top.Item);
}
}

  (2)递归版本

    public static void PrintListReversinglyRecursively(Node<int> head)
{
if (head != null)
{
if (head.Next != null)
{
PrintListReversinglyRecursively(head.Next);
} Console.Write("{0}", head.Item);
}
}

  两个版本的对比:上面的基于递归的代码看起来很简洁,但有个问题:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出显式用栈基于循环实现的代码的鲁棒性要好一些

3.2 单元测试

  (1)单元测试主入口

    // 测试主入口
static void PrintTestPortal(Node<int> head)
{
Console.WriteLine("-------Begin--------");
NormalPrint(head);
Console.WriteLine();
PrintListReversinglyIteratively(head);
Console.WriteLine();
PrintListReversinglyRecursively(head);
Console.WriteLine("\n-------End--------");
}
// 辅助方法:正序打印链表
static void NormalPrint(Node<int> head)
{
Node<int> temp = head;
while(temp != null)
{
Console.Write("{0}",temp.Item);
temp = temp.Next;
}
}

  在测试入口中,我们首先正序打印链表,然后使用循环版从尾到头打印链表,最后使用递归版从尾到头打印链表。

  (2)正常的多元素链表

    // 1->2->3->4->5
static void PrintTest1()
{
Console.WriteLine("TestCase1:");
SingleLinkedList<int> linkedList = new SingleLinkedList<int>();
linkedList.Add();
linkedList.Add();
linkedList.Add();
linkedList.Add();
linkedList.Add(); PrintTestPortal(linkedList.Head);
}

  (3)只有一个节点的链表

    // 只有一个节点的链表
static void PrintTest2()
{
Console.WriteLine("TestCase2:");
SingleLinkedList<int> linkedList = new SingleLinkedList<int>();
linkedList.Add(); PrintTestPortal(linkedList.Head);
}

  (4)鲁棒性测试:NULL

    // 空链表
static void PrintTest3()
{
Console.WriteLine("TestCase3:"); PrintTestPortal(null);
}

  测试结果如下图所示:

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

剑指Offer面试题:4.从尾到头打印链表的更多相关文章

  1. 剑指Offer - 九度1511 - 从尾到头打印链表

    剑指Offer - 九度1511 - 从尾到头打印链表2013-11-29 21:08 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例.每一组测试案例 ...

  2. JS 剑指Offer(四) 从尾到头打印链表

    题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...

  3. 剑指offer【03】- 从尾到头打印链表(4种实现方法)

    题目:从尾到头打印链表 考点:链表 题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 法一:ArrayList头插法 /** * public class ListNode ...

  4. 剑指offer(3)从尾到头打印链表

    题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ t ...

  5. 剑指offer第二版-6.从尾到头打印链表

    描述:输入一个链表的头节点,从尾到头打印每个节点的值. 思路:从尾到头打印,即为“先进后出”,则可以使用栈来处理:考虑递归的本质也是一个栈结构,可递归输出. 考点:对链表.栈.递归的理解. packa ...

  6. 【剑指Offer】3、从尾到头打印链表

      题目描述:   输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   解题思路:   (三种方法:借助栈.递归.列表的首位插入)   从头到尾打印链表比较简单,从尾到头很自然的可以 ...

  7. 剑指Offer编程题3——从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   题目解析 方法1:建立两个vector,第一个用来存储正向访问的数据,第二个用来反向存储. /** * struct L ...

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

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

  9. 剑指offer(5)——从尾到头打印链表

    题目: 输入一个链表的头结点,从尾到头反过来打印出每个结点的值.结点定义如下: public class ListNode { int val; ListNode next = null; ListN ...

  10. 剑指Offer_编程题之从尾到头打印链表

    题目描述 输入一个链表,从尾到头打印链表每个节点的值.

随机推荐

  1. Microsoft Visual Studio PDB文件相关事宜

    Microsoft Visual Studio PDB:调试的符号文件,程序数据库 (PDB) 文件保存着调试和项目状态信息,使用这些信息可以对程序的调试配置: 当以 /ZI 或 /Zi(用于 C/C ...

  2. lodash

    lodash常用函数一 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  3. ORACLE中常见SET指令

    1         SET TIMING ON 说明:显示SQL语句的运行时间.默认值为OFF. 在SQLPLUS中使用,时间精确到0.01秒.也就是10毫秒. 在PL/SQL DEVELOPER 中 ...

  4. Shell_1 简介

    1 Shell 变量 只读变量 使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变. #!/bin/bash -x varName="AAA" echo ...

  5. #pg学习#postgresql的安装

    1.按照官网给的步骤编译安装(Mac安装是比较容易的,相比Liunx) cd /Users/renlipeng/Desktop/postgresql-9.5.1 ./configure --prefi ...

  6. iOS Swift 数组 交换元素的两种方法

    swap(&arr[fromIndexPath.row], &arr[to.row]) (arr[fromIndexPath.row],arr[to.row]) = (arr[to.r ...

  7. jquery事件核心源码分析

    我们从绑定事件开始,一步步往下看: 以jquery.1.8.3为例,平时通过jquery绑定事件最常用的是on方法,大概分为下面3种类型: $(target).on('click',function( ...

  8. Cannot attach the file ‘{0}' as database '{1}'

    EF使用CodeFirst,当使用localDB时,删除mdf文件,会报“Cannot attach the file ‘{0}' as database '{1}'”错误. 解决方法如下: 1.打开 ...

  9. javaFx:使用弹出对话框 Alert

    javaFx8 自带的对话框非常好用,类似的使用方式如下: /** * 弹出一个通用的确定对话框 * @param p_header 对话框的信息标题 * @param p_message 对话框的信 ...

  10. Java jvisualvm简要说明

    jvisualvm能干什么:监控内存泄露,跟踪垃圾回收,执行时内存.cpu分析,线程分析... jvisualvm已经被集成在jdk1.6以上的版本中(不是jre).自身运行需要最低jdk1.6版本, ...