剑指Offer----面试题五:从尾到头打印链表
2016-05-19 22:32
661 查看
转载请注明出处</article/7845927.html>
链表问题:面试题5“从尾到头输出链表”、面试题13“在O(1)时间删除链表结点”、面试题15“链表中的倒数第k个结点”、面试题16“反转链表”、面试题17“合并两个排序的链表”、面试题37“两个链表的第一个公共结点”、面试题45“圆圈中最后剩下的数字”、面试题27“二叉搜索树与双向链表”、面试题26“复杂链表的赋值”。
提示:面试中如果打算修改输入的数据,最好先问面试官是不是允许做修改。
源代码:
源代码:
注意:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。
源文件List.cpp
测试文件
运行结果:
转载请注明出处</article/7845927.html>
前述:
链表的创建、结点的插入、结点的删除等操作都只需要20行左右的代码就能实现,其代码量比较适合面试。链表问题:面试题5“从尾到头输出链表”、面试题13“在O(1)时间删除链表结点”、面试题15“链表中的倒数第k个结点”、面试题16“反转链表”、面试题17“合并两个排序的链表”、面试题37“两个链表的第一个公共结点”、面试题45“圆圈中最后剩下的数字”、面试题27“二叉搜索树与双向链表”、面试题26“复杂链表的赋值”。
题目:
输入一个链表的头结点,从尾到头反过来点每个结点的值。提示:面试中如果打算修改输入的数据,最好先问面试官是不是允许做修改。
思路一:
遍历的顺序是从头到尾,可是却要从尾到头打印,符合“后进先出”栈的规律。源代码:
void printReversingly_Iteratively(ListNode *pHead) { if (pHead == NULL) { std::cout << "The list is empty" << std::endl; return; } else { std::stack<ListNode *> st; ListNode * pNew = pHead; while (pNew != NULL) { st.push(pNew); pNew = pNew->next; } while (!st.empty()) { std::cout << st.top()->element << " "; st.pop(); } } }
思路二:
既然想到用栈来实现这个函数,而递归的本质就是一个栈结构,所以本函数也可以用递归来解决。源代码:
void printReversingly_Recursively(ListNode *pHead) { if (pHead != NULL) { if (pHead->next != NULL) printReversingly_Recursively(pHead->next); std::cout << pHead->element << " "; } }
注意:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。
官方源代码(经过修改):
头文件List.h#ifndef LIST_NODE_H #define LIST_NODE_H namespace ListSpace { struct ListNode { int element; ListNode *next; }; ListNode * CreateListNode(int valude); void ConnectListNodes(ListNode *pCurrent, ListNode *pNext); void printListNode(ListNode *pHead); void printList(ListNode *pHead); void printReversingly_Iteratively(ListNode *pHead); void printReversingly_Recursively(ListNode *pHead); void DestoryList(ListNode **pHead); void AddToTail(ListNode ** pHead, int value); void RemoveNode(ListNode ** pHead, int value); } #endif
源文件List.cpp
#include"List.h"
#include<iostream>
#include<stack>
namespace ListSpace
{
ListNode * CreateListNode(int value)
{
ListNode *pNew = new ListNode();
pNew->element = value;
pNew->next = NULL;
return pNew;
}
void ConnectListNodes(ListNode *pCurrent, ListNode *pNext)
{
if (pCurrent == NULL)
std::cout << "Linking Error..." << std::endl;
else
{
pCurrent->next = pNext;
}
}
void printListNode(ListNode *pHead)
{
if (pHead == NULL)
std::cout << "The value of this node is empty" << std::endl;
else
std::cout << "The value of this node is " << pHead->element << std::endl;
}
void printList(ListNode *pHead)
{
if (pHead == NULL)
std::cout << "The list is empty" << std::endl;
else
{
ListNode *pNew = pHead;
while (pNew != NULL)
{
std::cout << pNew->element << " ";
pNew = pNew->next;
}
}
}
void printReversingly_Iteratively(ListNode *pHead) { if (pHead == NULL) { std::cout << "The list is empty" << std::endl; return; } else { std::stack<ListNode *> st; ListNode * pNew = pHead; while (pNew != NULL) { st.push(pNew); pNew = pNew->next; } while (!st.empty()) { std::cout << st.top()->element << " "; st.pop(); } } }
void printReversingly_Recursively(ListNode *pHead) { if (pHead != NULL) { if (pHead->next != NULL) printReversingly_Recursively(pHead->next); std::cout << pHead->element << " "; } }
void DestoryList(ListNode **pHead)
{
ListNode *pNew = *pHead;
while (pNew != NULL)
{
*pHead = (*pHead)->next;
delete pNew;
pNew = *pHead;
}
}
void AddToTail(ListNode ** pHead, int value)
{
ListNode *pNew = new ListNode();
pNew->element = value;
pNew->next = NULL;
if (*pHead == NULL)
*pHead = pNew;
else
{
//找到最后一个结点
ListNode *node = *pHead;
while (node ->next != NULL)
node = node->next;
node->next = pNew;
}
}
void RemoveNode(ListNode ** pHead, int value)
{
if (pHead == NULL || *pHead == NULL)
return;
ListNode *pToBeDeleted = NULL;
if ((*pHead)->element == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->next;
}
else
{
ListNode *node = *pHead;
while (node->next != NULL && node->next->element != value)
node = node->next;
if (node->next != NULL && node->next->element == value)
{
pToBeDeleted = node->next;
node->next = node->next->next;
}
}
if (pToBeDeleted != NULL)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
}
测试文件
#include"List.h" #include<iostream> using namespace ListSpace; void Test(ListNode* pHead) { printList(pHead); printReversingly_Recursively(pHead); printf("\n"); printReversingly_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); DestoryList(&pNode1); } // 只有一个结点的链表: 1 void Test2() { printf("\nTest2 begins.\n"); ListNode* pNode1 = CreateListNode(1); Test(pNode1); DestoryList(&pNode1); } // 空链表 void Test3() { printf("\nTest3 begins.\n"); Test(NULL); } int main() { Test1(); Test2(); Test3(); system("pause"); return 0; }
运行结果:
Test1 begins. 1 2 3 4 5 5 4 3 2 1 5 4 3 2 1 Test2 begins. 1 1 1 Test3 begins. The list is empty 请按任意键继续. . .
转载请注明出处</article/7845927.html>
相关文章推荐
- Android工程师面试— 复习知识点建议
- 职场小白进阶之路
- 值得程序员和设计师关注的微信公众号
- 闽江学院软件学院2015级学生职业人物访谈
- 程序员面试之软件测试面试问答
- 常见链表面试题之从尾到头打印链表
- 黑马程序员——java基础---按位& |、常量、变量
- 程序员面试笔试宝典学习记录(一)(常见面试笔试题目)
- 面试题03 二维数组中的查找
- 【43】Activity的几种LaunchMode及使用场景
- Java面试题及答案(二)
- 2016/5/19阿里巴巴Java暑假实习面试记录--武汉专场
- 面试中的排序算法总结
- Java集合相关面试问题和答案
- JAVA多线程和并发基础面试问答
- 优秀程序员无他-善假于物也
- 面试:数组:插入位置
- 面试算法题
- 剑指Offer----面试题四之相关题目
- 奋斗吧,程序员——第四十章 一面风情深有韵,半笺娇恨寄幽怀