剑指offer--面试题5
到现在为止,看过的书+代码有一定量了,并且也参加了个比赛,给自己的总体感觉:编程需要的是灵活的头脑,书里的东西只是讲个规则、思想,其实际实现可以千差万别! 潜在的规则+灵活的思维 = 程序!
在做面试题5时,发现Utilities文件夹下的内容太好了,基本上是那些数据结构的实现:链表、二叉树、树等(缺个图),准备通过学习这些代码来深入理解各个数据结构及其接口/成员函数。
拿该题来说,解决单链表!!!
题目:逆序打印单链表
一、自己写单链表类及其操作
花了一下午时间,无语了。。。
1、List.h
//单链表数据结构及基本操作 //最大节点数
const int MAXLENGTH = ;
//节点
struct ListNode
{
int m_Value;
ListNode* m_pNext;
}; //List类
class List
{
private:
ListNode LNode;
int MaxLength;
public:
//constructor and deconstructor
List();
virtual ~List();
//单链表操作
//1. 创建节点
ListNode* CreateListNode(int value);
//2. 创建链表或者将节点加到链尾
void CreateFrontOrAddToTail(ListNode** pHead, int value);
//3. 在第i个节点之前插入新的节点
void ListInsert(ListNode* pHead, int i, int value);
//4. 删除value=e的节点
void RemoveListNode(ListNode** pHead,int value);
//5. 查找第一个value=e的节点
int FindListNode(ListNode* pHead,int value);
//6. 销毁链表
void DestoryList(ListNode* pHead);
//7. 链表元素个数
int ListLength(ListNode* pHead);
};
2、List.cpp
//List.cpp #include "List.h"
#include <iostream> List::List()
{
LNode.m_Value = ;
LNode.m_pNext = NULL;
MaxLength = MAXLENGTH;
} List::~List()
{ } //1. 创建节点
ListNode* List::CreateListNode(int value)
{
ListNode* pNew = new ListNode;
pNew->m_Value = value;
pNew->m_pNext = NULL;
}
//2. 创建链表或者将节点加到链尾
void List::CreateFrontOrAddToTail(ListNode** pHead, int value)
{
if(pHead == NULL)
return;
ListNode* pNew = CreateListNode(value);
if(*pHead == NULL) //空链表
*pHead = pNew;
else
{
ListNode* pNode = *pHead;
while(pNode->m_pNext != NULL)
pNode = pNode->m_pNext;
pNode->m_pNext = pNew;
} }
//3. 在第i个节点之前插入新的节点
void List::ListInsert(ListNode* pHead, int i, int value)
{
if(pHead == NULL || i >= MaxLength)
return;
ListNode* pNew = CreateListNode(value);
ListNode* pNode = *pHead;
ListNode* preNode = *pHead;
i--;
while(i && pNode->m_pNext != NULL)
{
preNode = pNode;
pNode = pNode->m_pNext;
i--;
}
if(i == )
{
preNode->m_pNext = pNew;
pNew->m_pNext = pNode;
}
else
cout<<"Failed!"<<endl;
}
//4. 删除value=e的第一个节点
bool List::RemoveListNode(ListNode** pHead,int value)
{
if(pHead == NULL || *pHead == NULL)
return false;
ListNode* pToBeDeleted = NULL;
if((*pHead)->m_Value == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
}
else
{
ListNode* pNode = *pHead;
while(pNode->m_pNext != NULL && pNode->m_pNext->m_Value != value)
pNode = pNode->m_pNext;
if(pNode->m_pNext != NULL && pNode->m_pNext->m_Value == value)
{
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
}
}
if(pToBeDeleted != NULL)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
return true;
}
return false;
} //5. 查找第一个value=e的节点,返回其位置
int List::FindListNode(ListNode* pHead,int value)
{
int i = ;
ListNode* pNode = pHead;
while(pNode != NULL && pNode->m_Value != value)
{
i++;
pNode = pNode->m_pNext;
}
if(pNode != NULL && pNode->m_Value == value)
return i;
else
return ; }
//6. 销毁链表
void List::DestoryList(ListNode* pHead)
{
ListNode* pNode = pHead;
while(pHead != NULL)
{
pNode = pHead;
pHead = pHead->m_pNext;
delete pNode;
}
}
//7. 链表元素个数
int List::ListLength(ListNode* pHead)
{
ListNode* pNode = pHead;
int i = ;
while(pNode != NULL)
{
i++;
pNode = pNode->m_pNext;
}
return i;
}
未测试过。。。因为想继续做面试题5了,进度太慢了!!!
二、面试题5整理:
逆序打印单链表,首先想到的便是通过扫描链表,并同时用栈存储每个值,最后利用栈的LIFO特点打印即可。但是,鉴于自己的水平,并没有用过C++中stl里的stack,因此想了另一种方法,即将扫描链表时所得到的值存入到一个数组中,最后逆序打印即可。这种方法固然可行,但效率上必然低于栈的。所以综合以上分析,又学习了stl中的stack,具体见上一篇博客。最后,怎么也没想到可以用递归的方式求解。。。
根据作者代码思想,做了如下改动:
void PrintListReversingly_Iteratively(ListNode* pHead)
{
std::stack<int> nodes; ListNode* pNode = pHead;
while(pNode != NULL)
{
nodes.push(pNode->m_nValue);
pNode = pNode->m_pNext;
} int value;
while(!nodes.empty())
{
value = nodes.top();
printf("%d\t", value);
nodes.pop();
}
}
这里将stack的元素设置为了m_nValue的类型,仔细想想后,认为还是原代码更合理,原因如下:
原代码中,节点地址入栈,因此栈中每个元素所占存储是固定的,在32位操作系统下,指针(地址)占4字节;但如果存储的是节点数据元素,那么每个元素所占存储很可能大于4字节;
void PrintListReversingly_Recursively(ListNode* pHead)
{
if(pHead == NULL)
{
return;
}
else
{
PrintListReversingly_Recursively(pHead->m_pNext);
printf("%d\t", pHead->m_nValue);
}
}
剑指offer--面试题5的更多相关文章
- 剑指Offer:面试题15——链表中倒数第k个结点(java实现)
问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...
- 剑指offer面试题3 二维数组中的查找(c)
剑指offer面试题三:
- 剑指Offer——笔试题+知识点总结
剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解
剑指offer 面试题23:从上往下打印二叉树 参与人数:4853 时间限制:1秒 空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...
- C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解
剑指offer 面试题39:判断平衡二叉树 提交网址: http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
- C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...
- C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...
- C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解
剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...
随机推荐
- IE6中position:fixed无效问题解决
在做页面右下脚对话框时,直接使用position:fixed;大部分浏览器很容易就能做到,但是在IE6中却发现不行,原来是IE6不支持position:fixed;这个属性. 虽然用JS肯定能解决这个 ...
- spark写入Oracle 报错 java.lang.ArrayIndexOutOfBoundsException: -32423
原因: oracle 10g的驱动执行的批量提交只支持32768个参数,如果表的字段多于32个,就会出现该异常 解决办法: 升级oracle的驱动版本,换成ojdbc6.jar
- 实现百度外卖APP个人中心头像"浪"起来的动画效果
让你的头像浪起来~~~~~ DEMO 地址:网页链接,点击下载 你需要知道的 CADisplayLink 简单的说就是一定时器,其根本利用刷帧和屏幕频率一样来重绘渲染页面. 其创建方式: [Objec ...
- UI1_UIScrollView
// // AppDelegate.m // UI1_UIScrollView // // Created by zhangxueming on 15/7/10. // Copyright (c) 2 ...
- [翻译.每月一译.每日一段]Exploring Fonts with DirectWrite and Modern C++
Windows with C++ Exploring Fonts with DirectWrite and Modern C++ Kenny Kerr DirectWrite is an incred ...
- callback调用测试
<html> <head> <script> var context="全局"; var testObj={ context:"初始& ...
- 什么是AJAX技术及其常识
1.什么是Ajax? Ajax的全称是:AsynchronousJavaScript+XML 2.Ajax的定义: Ajax不是一个技术,它实际上是几种技术,每种技术都有其独特这处,合在一起就成了一个 ...
- js实现雪花飘落效果的代码
使用js实现雪花飘落的效果,用html5绘布加js写的雪花飘效果 . 代码: <html> <head> <script> /** * js与html5实现的雪花飘 ...
- ASP专栏——ASP生成静态文件(用于大量文章)
对于Web开发人员来说,生成静态文件这个概念并不陌生. 对于Web开发来说,如何能避免客户端访问时不停的查询数据库?现在比较常用的有两种方法,一种是使用缓存技术,将查询出来的结果缓存至缓存框架中,以后 ...
- Oracle内存组件理论篇一
目标 1.SGA结构 2.PGA结构 1.SGA Shared pool 1).共享池是对SQL.PL/SQL程序进行语法分析.编译.执行的内存区域. 在执行SELECT * FROM emp语句时, ...