从尾到头打印链表(C++和Python 实现)
2017-09-26 08:31
519 查看
(说明:本博客中的题目、题目详细说明及参考代码均摘自 “何海涛《剑指Offer:名企面试官精讲典型编程题》2012年”)
进一步详细说明:
不允许在打印时修改链表的结构。链表结点可定义为:
具体实现可以采用两种方法:迭代和递归。正如书中所说,“递归在本质上就是一个栈结构”。递归实现,从理论上,完全可以利用栈结构转换为非递归实现,即迭代方法。
注:使用 Python 利用函数建立链表时,需要注意函数参数的值传递和引用传递,此为易错点。
View Code
10. 参考代码下载
项目 05_PrintListInReversedOrder 下载: 百度网盘
何海涛《剑指Offer:名企面试官精讲典型编程题》 所有参考代码下载:百度网盘
题目
输入一个链表的头结点, 从尾到头反过来打印出每个结点的值。进一步详细说明:
不允许在打印时修改链表的结构。链表结点可定义为:
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 memory DestroyLinkedList(&head); // 易漏点 } int main() { unitest(); return 0; }
Python 实现
#!/usr/bin/python # -*- coding: utf8 -*- from __future__ import print_function class ListNode: def __init__(self, value, next_node=None): self.value = value self.next = next_node def add_to_tail(head, value): q = ListNode(value) if head is None: head = q else: p = head while p.next is not None: p = p.next p.next = q return head def print_list_reversely_iteratively(head): p = head stack = [] # Push into stack while p is not None: stack.append(p.value) p = p.next # Pop from stack while stack: elem = stack.pop() print(elem, end=', ') print('') def print_list_reversely_recursively(head): if head is None: return if 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!") return p = head while p is not None: print(p.value, end='') if p.next is not None: print(' -> ', end='') p = p.next print('') def unitest(): linked_list = None linked_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/ 目录)// 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.相关文章推荐
- 从尾到头打印链表 【C++实现】
- 剑指offer--python --c++--从尾到头打印链表
- 面试题5:从尾到头打印链表的c++代码实现
- 剑指offer第三题【从尾到头打印链表】c++实现
- python 实现剑指offer系列3:从尾到头打印链表
- JAVA实现从尾到头打印链表(《剑指offer》)
- 【C++】用类实现单向单链表的尾插PushBack(),尾删PopBack(),打印PrintSlist()。
- 剑指Offer:面试题5——从尾到头打印链表(java实现)
- 剑指offer--面试题5:从尾到头打印链表--Java实现
- C++ 递归实现反向打印一个链表(引入wrapper function的概念)
- 数据结构与算法分析笔记与总结(java实现)--链表1:从尾到头打印链表值问题
- 剑指offer_面试题5_从尾到头打印链表(栈和递归实现)
- 从尾到头打印链表中每个节点的值(采用栈实现)
- 剑指offer(C++)——从尾到头打印链表
- 两种方法实现:输入一个链表,从尾到头打印链表每个节点的值
- 打印100以内的素数(质数)----C++实现、python实现
- 学习Stack,并实现从尾到头打印链表LinkedList
- 剑指offer:从尾到头打印链表代码实现
- 剑指Offer——从尾到头打印链表——C++
- 剑指offer 面试题5 从尾到头打印链表(递归实现)