题目描述:输入一个链表的头结点,从尾到头反过来打印出每个节点的值。
分析:从尾到头打印,那就是先进后出,根据这个可以想想能不能用栈实现,这个是可以的。先按顺序把节点的值入栈,所有值入栈之后再出栈,直到栈为空。除了使用栈之外还有什么方法吗?有的,还有一个和栈类似,那就是递归,递归在本质上就是一个栈结构,所以就有两种解法。
代码如下:
声明节点对象,并提供必要的方法:
class ListNode
{
public object m_nValue;
public ListNode m_pNext;
public ListNode(object data=null)
{
m_nValue = data;
m_pNext = null;
}
//关联两个节点
internal static void ConnectListNodes(ListNode currentNode,ListNode nextNode)
{
currentNode.m_pNext = nextNode;
}
//删除整个链表
internal static void DestroyListNodes(ListNode pHead)
{
ListNode currentNode = pHead;
ListNode nextNode = null;
while(currentNode!=null)
{
nextNode = currentNode.m_pNext;
//执行删除(没找到对应的方法)
currentNode = nextNode;
}
}
}
将值存入栈的解法:
private static void PrintListReversingly_Iteratively(ListNode pHead)
{
Stack<object> nodes = new Stack<object>();
ListNode pNode = pHead;
//入栈
while(pNode!=null)
{
nodes.Push(pNode.m_nValue);
pNode = pNode.m_pNext;
}
//打印并出栈
while(nodes.Count>0)
{
object value = nodes.Peek();
Console.Write("{0} ", value);
nodes.Pop();
}
}
递归解法:
private static void PrintListReversingly_Recursively(ListNode pHead)
{
ListNode pNode = pHead;
if(pNode.m_pNext!=null)
{
PrintListReversingly_Recursively(pNode.m_pNext);
}
Console.Write("{0} ", pNode.m_nValue);
}
测试方法:
static void Test(ListNode pHead)
{
PrintListReversingly_Iteratively(pHead);
Console.WriteLine();
PrintListReversingly_Recursively(pHead);
Console.WriteLine();
}
// 1->2->3->4->5
static void Test1()
{
ListNode pNode1 = new ListNode(1);
ListNode pNode2 = new ListNode(2);
ListNode pNode3 = new ListNode(3);
ListNode pNode4 = new ListNode(4);
ListNode pNode5 = new ListNode(5);
ListNode.ConnectListNodes(pNode1, pNode2);
ListNode.ConnectListNodes(pNode2, pNode3);
ListNode.ConnectListNodes(pNode3, pNode4);
ListNode.ConnectListNodes(pNode4, pNode5);
Test(pNode1);
}
//只有一个节点的链表
static void Test2()
{
ListNode pNode1 = new ListNode(1);
Test(pNode1);
}
//空链表
static void Test3()
{
ListNode pNode1 = new ListNode();
Test(pNode1);
}
Main方法:
static void Main(string[] args)
{
Test1();
Test2();
Test3();
Console.ReadKey();
}
总结:要点就是要想到栈,使用递归方法要小心,当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。