(说明:本博客中的题目题目详细说明参考代码均摘自 “何海涛《剑指Offer:名企面试官精讲典型编程题》2012年”)

题目

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

进一步详细说明:
不允许在打印时修改链表的结构。链表结点可定义为:

struct ListNode
{int m_nKey;ListNode* m_pNext;
};

算法设计思想

正常情况,遍历链表都是从前到后的,即从头到尾。如果从尾到头打印链表元素,可以借助栈的 “后入先出” (Last in, First out)的性质,在正向遍历时将链表元素依次压栈,当到达链表末尾时,再依次弹出并打印。

具体实现可以采用两种方法:迭代和递归。正如书中所说,“递归在本质上就是一个栈结构”。递归实现,从理论上,完全可以利用栈结构转换为非递归实现,即迭代方法。

C++ 实现

#include <iostream>
#include <stack>struct ListNode
{int  m_nKey;ListNode* m_pNext;
};void AddToTail(ListNode** pHead, int value)
{ListNode* pNew = new ListNode();pNew->m_nKey = value;pNew->m_pNext = NULL;if (*pHead == NULL){*pHead = pNew;}else{ListNode* pNode = *pHead;while (pNode->m_pNext != NULL)pNode = pNode->m_pNext;pNode->m_pNext = pNew;}
}void PrintLinkedList(const ListNode* head)
{if (head == NULL)  // 易漏点return;ListNode* ptr = (ListNode*) head;while (ptr->m_pNext != NULL){std::cout << ptr->m_nKey << " -> ";ptr = ptr->m_pNext;}std::cout << ptr->m_nKey << std::endl;
}void DestroyLinkedList(ListNode** pHead)
{if (pHead == NULL || *pHead == NULL)  // 易漏点return;ListNode* pNode = NULL;while (*pHead != NULL){pNode = *pHead;*pHead = (*pHead)->m_pNext;delete pNode;}
}// Iterative method
void PrintListReversingly_Iteratively(const ListNode* pHead)
{if (pHead == NULL)return;ListNode* pNode = (ListNode*) pHead;std::stack<ListNode*> nodes;while (pNode != NULL){nodes.push(pNode);pNode = pNode->m_pNext;}while (!nodes.empty()){pNode = nodes.top();nodes.pop();std::cout << pNode->m_nKey << ", ";}std::cout << std::endl;
}// Recursive method
void PrintListReversingly_Recursively(const ListNode* pHead)
{if (pHead != NULL){if (pHead->m_pNext != NULL){PrintListReversingly_Recursively(pHead->m_pNext);}std::cout << pHead->m_nKey << ", ";}
}void unitest()
{ListNode* head = NULL;AddToTail(&head, 1);AddToTail(&head, 2);AddToTail(&head, 3);AddToTail(&head, 5);AddToTail(&head, 4);std::cout << "Print forward: ";PrintLinkedList(head);std::cout << "Print reversely iteratively: ";PrintListReversingly_Iteratively(head);std::cout << "Print reversely recursively: ";PrintListReversingly_Recursively(head);// Release memoryDestroyLinkedList(&head);   // 易漏点
}int main()
{unitest();return 0;
}

Python 实现

#!/usr/bin/python
# -*- coding: utf8 -*-from __future__ import print_functionclass ListNode:def __init__(self, value, next_node=None):self.value = valueself.next = next_nodedef add_to_tail(head, value):q = ListNode(value)if head is None:head = qelse:p = headwhile p.next is not None:p = p.nextp.next = qreturn head def print_list_reversely_iteratively(head):p = headstack = []# Push into stackwhile p is not None:stack.append(p.value)p = p.next# Pop from stackwhile stack:elem = stack.pop()print(elem, end=', ')print('')def print_list_reversely_recursively(head):if head is None:returnif head.next is not None:print_list_reversely_recursively(head.next)print(head.value, end=', ')def print_linked_list_forward(head):if head is None:print("This linked list is empty!")returnp = headwhile p is not None:print(p.value, end='')if p.next is not None:print(' -> ', end='')p = p.nextprint('')def unitest():linked_list = Nonelinked_list = add_to_tail(linked_list, 1)linked_list = add_to_tail(linked_list, 2)linked_list = add_to_tail(linked_list, 3)linked_list = add_to_tail(linked_list, 5)linked_list = add_to_tail(linked_list, 4)print("Print forward: ", end='')print_linked_list_forward(linked_list)print("Print reversely iteratively: ", end='') print_list_reversely_iteratively(linked_list)print("Print reversely recursively: ", end='') print_list_reversely_recursively(linked_list)if __name__ == '__main__':unitest()

注:使用 Python 利用函数建立链表时,需要注意函数参数的值传递和引用传递,此为易错点

参考代码

1. targetver.h (05_PrintListInReversedOrder/ 目录)

#pragma once// The following macros define the minimum required platform.  The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application.  The macros work by enabling all features available on platform versions up to and
// including the version specified.// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
#endif

View Code

2. stdafx.h (05_PrintListInReversedOrder/ 目录)

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once#include "targetver.h"#include <stdio.h>
#include <tchar.h>// TODO: reference additional headers your program requires here

View Code

3. stdafx.cpp (05_PrintListInReversedOrder/ 目录)

// stdafx.cpp : source file that includes just the standard includes
// PrintListInReversedOrder.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View Code

4. PrintListInReversedOrder.cpp

// PrintListInReversedOrder.cpp : Defines the entry point for the console application.
//// 《剑指Offer——名企面试官精讲典型编程题》代码
// 著作权所有者:何海涛

#include "stdafx.h"
#include "..\Utilities\List.h"
#include <stack>void PrintListReversingly_Iteratively(ListNode* pHead)
{std::stack<ListNode*> nodes;ListNode* pNode = pHead;while(pNode != NULL){nodes.push(pNode);pNode = pNode->m_pNext;}while(!nodes.empty()){pNode = nodes.top();printf("%d\t", pNode->m_nValue);nodes.pop();}
}void PrintListReversingly_Recursively(ListNode* pHead)
{if(pHead != NULL){if (pHead->m_pNext != NULL){PrintListReversingly_Recursively(pHead->m_pNext);}printf("%d\t", pHead->m_nValue);}
}void Test(ListNode* pHead)
{PrintList(pHead);PrintListReversingly_Iteratively(pHead);printf("\n");PrintListReversingly_Recursively(pHead);
}// 1->2->3->4->5
void Test1()
{printf("\nTest1 begins.\n");ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);Test(pNode1);DestroyList(pNode1);
}// 只有一个结点的链表: 1
void Test2()
{printf("\nTest2 begins.\n");ListNode* pNode1 = CreateListNode(1);Test(pNode1);DestroyList(pNode1);
}// 空链表
void Test3()
{printf("\nTest3 begins.\n");Test(NULL);
}int _tmain(int argc, _TCHAR* argv[])
{Test1();Test2();Test3();return 0;
}

View Code

5. targetver.h (Utilities/ 目录)

#pragma once// The following macros define the minimum required platform.  The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application.  The macros work by enabling all features available on platform versions up to and
// including the version specified.// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER                          // Specifies that the minimum required platform is Windows Vista.
#define WINVER 0x0600           // Change this to the appropriate value to target other versions of Windows.
#endif#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
#endif#ifndef _WIN32_WINDOWS          // Specifies that the minimum required platform is Windows 98.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif#ifndef _WIN32_IE                       // Specifies that the minimum required platform is Internet Explorer 7.0.
#define _WIN32_IE 0x0700        // Change this to the appropriate value to target other versions of IE.
#endif

View Code

6. stdafx.h (Utilities/ 目录)

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once#include "targetver.h"#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <stdio.h>// TODO: reference additional headers your program requires here

View Code

7. stdafx.cpp (Utilities/ 目录)

// stdafx.cpp : source file that includes just the standard includes
// Utilities.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View Code

8. List.h

// 《剑指Offer——名企面试官精讲典型编程题》代码
// 著作权所有者:何海涛struct ListNode
{int       m_nValue;ListNode* m_pNext;
};__declspec( dllexport ) ListNode* CreateListNode(int value);
__declspec( dllexport ) void ConnectListNodes(ListNode* pCurrent, ListNode* pNext);
__declspec( dllexport ) void PrintListNode(ListNode* pNode);
__declspec( dllexport ) void PrintList(ListNode* pHead);
__declspec( dllexport ) void DestroyList(ListNode* pHead);
__declspec( dllexport ) void AddToTail(ListNode** pHead, int value);
__declspec( dllexport ) void RemoveNode(ListNode** pHead, int value);

View Code

9. List.cpp

// Utilities.cpp : Defines the exported functions for the DLL application.
//// 《剑指Offer——名企面试官精讲典型编程题》代码
// 著作权所有者:何海涛

#include "stdafx.h"
#include "list.h"
#include <stdio.h>
#include <stdlib.h>ListNode* CreateListNode(int value)
{ListNode* pNode = new ListNode();pNode->m_nValue = value;pNode->m_pNext = NULL;return pNode;
}void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{if(pCurrent == NULL){printf("Error to connect two nodes.\n");exit(1);}pCurrent->m_pNext = pNext;
}void PrintListNode(ListNode* pNode)
{ if(pNode == NULL){printf("The node is NULL\n");}else{printf("The key in node is %d.\n", pNode->m_nValue);}
}void PrintList(ListNode* pHead)
{printf("PrintList starts.\n");ListNode* pNode = pHead;while(pNode != NULL){printf("%d\t", pNode->m_nValue);pNode = pNode->m_pNext;}printf("\nPrintList ends.\n");
}void DestroyList(ListNode* pHead)
{ListNode* pNode = pHead;while(pNode != NULL){pHead = pHead->m_pNext;delete pNode;pNode = pHead;}
}void AddToTail(ListNode** pHead, int value)
{ListNode* pNew = new ListNode();pNew->m_nValue = value;pNew->m_pNext = NULL;if(*pHead == NULL){*pHead = pNew;}else{ListNode* pNode = *pHead;while(pNode->m_pNext != NULL)pNode = pNode->m_pNext;pNode->m_pNext = pNew;}
}void RemoveNode(ListNode** pHead, int value)
{if(pHead == NULL || *pHead == NULL)return;ListNode* pToBeDeleted = NULL;if((*pHead)->m_nValue == value){pToBeDeleted = *pHead;*pHead = (*pHead)->m_pNext;}else{ListNode* pNode = *pHead;while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)pNode = pNode->m_pNext;if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value){pToBeDeleted = pNode->m_pNext;pNode->m_pNext = pNode->m_pNext->m_pNext;}}if(pToBeDeleted != NULL){delete pToBeDeleted;pToBeDeleted = NULL;}
}

View Code

10. 参考代码下载

项目 05_PrintListInReversedOrder 下载: 百度网盘

何海涛《剑指Offer:名企面试官精讲典型编程题》 所有参考代码下载:百度网盘

参考资料

[1]  何海涛. 剑指 Offer:名企面试官精讲典型编程题 [M]. 北京:电子工业出版社,2012. 49-53.

转载于:https://www.cnblogs.com/klchang/p/7590302.html

从尾到头打印链表(C++和Python 实现)相关推荐

  1. 【剑指Offer专题】链表系列:从尾到头打印链表、反转链表、回文链表、合并两个排序的链表(C++和Python实现)...

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 剑指Offer(三):从尾到头打印链表 输入一个链表的头节点,从尾到头反过来返回每 ...

  2. python 从尾到头打印链表

    从尾到头打印链表 输入一个链表的头节点,从尾到头反过来返回每个节点的值 (用数组返回).示例 1:输入:head = [1,3,2] 输出:[2,3,1] 提供三种题解 # Definition fo ...

  3. 剑指offer:面试题06. 从尾到头打印链表

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

  4. 《LeetCode力扣练习》剑指 Offer 06. 从尾到头打印链表 Java

    <LeetCode力扣练习>剑指 Offer 06. 从尾到头打印链表 Java 一.资源 题目: 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入: ...

  5. java从尾到头打印链表数据_Java编程实现从尾到头打印链表代码实例

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

  6. JAVA实现从尾到头打印链表(《剑指offer》)

    最近在刷<剑指offer>里的编程题,但是网上关于<剑指offer>的解答多半是C或者C++的,而且官方(作者)也是在用C++进行讲解,这里自己用java写了一些题目的解答代码 ...

  7. 【剑指Offer】从尾到头打印链表

    剑指Offer 从尾到头打印链表 题目描述 解法1 实现代码 一点补充 题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解法1 这道题主要思路是while循环从头遍历整个列 ...

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

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

  9. LeetCode-剑指 Offer 06. 从尾到头打印链表

    剑指 Offer 06. 从尾到头打印链表 思路一:翻转 1:用vector存从头到尾的每个节点值 2:返回时候用reverse翻转一下 时间复杂度:O(n) 空间复杂度:O(n) /*** Defi ...

最新文章

  1. Google 的自动驾驶车出事故,被人类撞的
  2. varchar保存带格式的数据_软件测试必备之数据库知识(一)
  3. vs插件ZunKoIDE
  4. Ribbon_窗体_实现Ribbon风格的窗体
  5. 你知道生气有多可怕吗?“气死人”是有科学依据的
  6. 东北大学计算机技术考研大纲,东北大学考研大纲
  7. Oracle Partition By 的使用
  8. PHP学习笔记:利用百度api实现手机归属地查询
  9. Python 开源电子书资源
  10. Dockerfile制作自定义镜像
  11. 纠结的链接——ln、ln -s、fs.symlink、require
  12. 快速核对两个表格数据
  13. Shannon-Fano编码——原理与实现
  14. react-native-webrtc之采坑之旅
  15. 垃圾小白羊的leetcode刷题记录7
  16. reactjs 视频教程
  17. 【工具】hadoop国内下载镜像
  18. 一键自动生成字幕、制作双语字幕,懒人必备
  19. 金碟软件资产负债表中JC,JD,DY,DC表示的是什么
  20. jquery 动态按钮绑定点击事件

热门文章

  1. PR字幕预设|视频文字闪烁标题闪动特效PR预设
  2. MDM三权分立及分类分级权限说明
  3. 怎样才能掌握好计算机知识,简析怎样才能上好计算机课
  4. 关于MVC控制器导出Excel时MemoryStream流已关闭的问题
  5. 隐藏win10任务栏输入法M图标
  6. bat文件刷屏,请规范命名
  7. Keil4工程用Keil5继续开发,编译报错问题探究
  8. 神经网络权重是什么意思,神经网络权重调整方法
  9. php|thinkphp程序合成图片+文字+图片大小调整+正方形转换圆角+去除白色边框
  10. JAVA音视频解决方案----音频处理方案