ImageVerifierCode 换一换
格式:DOC , 页数:5 ,大小:41.50KB ,
资源ID:1336194      下载积分:5000 积分
快捷下载
登录下载
邮箱/手机:
温馨提示:
如需开发票,请勿充值!快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝扫码支付 微信扫码支付   
注意:如需开发票,请勿充值!
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【http://www.mydoc123.com/d-1336194.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(【计算机类职业资格】程序员面试-试卷2及答案解析.doc)为本站会员(syndromehi216)主动上传,麦多课文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知麦多课文库(发送邮件至master@mydoc123.com或直接QQ联系客服),我们立即给予删除!

【计算机类职业资格】程序员面试-试卷2及答案解析.doc

1、程序员面试-试卷 2 及答案解析(总分:8.00,做题时间:90 分钟)1.输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。 比如将二元查找树 10 / 6 14 / / 4 8 12 16 转换成双向链表4=6=8=10=12=14=16。(分数:2.00)_2.定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素。要求函数 min、push 以及 pop 的时间复杂度都是 O(1)。(分数:2.00)_3.输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组

2、的和的最大值。要求时间复杂度为 O(n)。例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,因此输出为该子数组的和 18。(分数:2.00)_4.输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如输入整数 22 和如下二元树 10 / 5 12 / 4 7 则打印出两条路径:10, 12 和 10, 5, 7。二元树结点的数据结构定义为:struct BinaryTreeNode / a node in the binary tree int

3、m_nValue; / value of node BinaryTreeNode *m_pLeft; / left child of node BinaryTreeNode *m_pRight; / right child of node;(分数:2.00)_程序员面试-试卷 2 答案解析(总分:8.00,做题时间:90 分钟)1.输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。 比如将二元查找树 10 / 6 14 / / 4 8 12 16 转换成双向链表4=6=8=10=12=14=16。(分数:2.00)_正确答案:(正确答案:思

4、路一:当我们到达某一结点准备调整以该结点为根结点的子树时,先调整其左子树将左子树转换成一个排好序的左子链表,再调整其右子树转换右子链表。最近链接左子链表的最右结点(左子树的最大结点)、当前结点和右子链表的最左结点(右子树的最小结点)。从树的根结点开始递归调整所有结点。 思路二:我们可以中序遍历整棵树。按照这个方式遍历树,比较小的结点先访问。如果我们每访问一个结点,假设之前访问过的结点已经调整成一个排序双向链表,我们再把调整当前结点的指针将其链接到链表的末尾。当所有结点都访问过之后,整棵树也就转换成一个排序双向链表了。 参考代码: 首先我们定义二元查找树结点的数据结构如下: struct BST

5、reeNode / a node in the binary search tree int m_nValue; / value of node BSTreeNode *m_pLeft; / left child of node BSTreeNode *m_pRight; / right child of node ; 思路一对应的代码: / / Covert a sub binary-search-tree into a sorted double-linked list / Input: pNode - the head of the sub tree / asRight - whethe

6、r pNode is the right child of its parent / Output: if asRight is true, return the least node in the sub-tree / else return the greatest node in the sub-tree / BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight) if(!pNode) return NULL; BSTreeNode *pLeft = NULL; BSTreeNode *pRight = NULL; / Conve

7、rt the left sub-tree if(pNode-m_pLeft) pLeft = ConvertNode(pNode-m_pLeft, false); / Connect the greatest node in the left sub-tree to the current node if(pLeft) pLeft-m_pRight = pNode; pNode-m_pLeft = pLeft; / Convert the right sub-tree if(pNode-m_pRight) pRight = ConvertNode(pNode-m_pRight, true);

8、/ Connect the least node in the right sub-tree to the current node if(pRight) pNode-m_pRight = pRight; pRight-m_pLeft = pNode; BSTreeNode *pTemp = pNode; / If the current node is the right child of its parent, / return the least node in the tree whose root is the current node if(asRight) while(pTemp

9、-m_pLeft) pTemp = pTemp-m_pLeft; / If the current node is the left child of its parent, / return the greatest node in the tree whose root is the current node else while(pTemp-m_pRight) pTemp = pTemp-m_pRight; return pTemp; / / Covert a binary search tree into a sorted double-linked list / Input: the

10、 head of tree / Output: the head of sorted double-linked list / BSTreeNode* Convert(BSTreeNode* pHeadOfTree) / As we want to return the head of the sorted double-linked list, / we set the second parameter to be true return ConvertNode(pHeadOfTree, true); 思路二对应的代码: / / Covert a sub binary-search-tree

11、 into a sorted double-linked list / Input: pNode - the head of the sub tree / pLastNodeInList - the tail of the double-linked list / void ConvertNode(BSTreeNode* pNode, BSTreeNode* BSTreeNode *pCurrent = pNode; / Convert the left sub-tree if (pCurrent-m_pLeft != NULL) ConvertNode(pCurrent-m_pLeft, p

12、LastNodeInList); / Put the current node into the double-linked list pCurrent-m_pLeft = pLastNodeInList; if(pLastNodeInList != NULL) pLastNodeInList-m_pRight = pCurrent; pLastNodeInList = pCurrent; / Convert the right sub-tree if (pCurrent-m_pRight != NULL) ConvertNode(pCurrent-m_pRight, pLastNodeInL

13、ist); / / Covert a binary search tree into a sorted double-linked list / Input: pHeadOfTree - the head of tree / Output: the head of sorted double-linked list / BSTreeNode* Convert_Solution1(BSTreeNode* pHeadOfTree) BSTreeNode *pLastNodeInList = NULL; ConvertNode(pHeadOfTree, pLastNodeInList); / Get

14、 the head of the double-linked list BSTreeNode *pHeadOfList = pLastNodeInList; while(pHeadOfList return pHeadOfList; )解析:2.定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素。要求函数 min、push 以及 pop 的时间复杂度都是 O(1)。(分数:2.00)_正确答案:(正确答案:我看到这道题目时,第一反应就是每次 push 一个新元素时,将栈里所有逆序元素排序。这样栈顶元素将是最小元素。但由于不能保证最后 push 进栈的元素最先出栈,这种思路设计的

15、数据结构已经不是一个栈了。 在栈里添加一个成员变量存放最小元素(或最小元素的位置)。每次 push 一个新元素进栈的时候,如果该元素比当前的最小元素还要小,则更新最小元素。 乍一看这样思路挺好的。但仔细一想,该思路存在一个重要的问题:如果当前最小元素被 pop 出去,如何才能得到下一个最小元素?因此仅仅只添加一个成员变量存放最小元素(或最小元素的位置)是不够的。我们需要一个辅助栈。每次 push 一个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push 到辅助栈中;每次 pop 一个元素出栈的时候,同时pop 辅助栈

16、。 参考代码: #include #include template class CStackWithMin public: CStackWithMin(void) virtual CStackWithMin(void) T const T void push(const T void pop(void); const T private: Tm_data;/ theelements of stack size_tm_minIndex;/ the indicesof minimum elements ; / get the last element of mutable stack templ

17、ate T / get the last element of non-mutable stack template const T / insert an elment at the end of stack template void CStackWithMin:push(const T / set the index of minimum elment in m_data at the end of m_minIndex if(m_minIndex.size() = 0) m_minIndex.push_back(0); else if(value 0); assert(m_minInd

18、ex.size() 0); return m_datam_minIndex.back(); 举个例子演示上述代码的运行过程: 步骤 数据栈 辅助栈 最小值 1.push 3 3 0 3 2.push 4 3,4 0,0 3 3.push 2 3,4,2 0,0,2 2 4.push 1 3,4,2,1 0,0,2,3 1 5.pop 3,4,2 0,0,2 2 6.pop 3,4 0,0 3 7.push 0 3,4,0 0,0,2 0 讨论:如果思路正确,编写上述代码不是一件很难的事情。但如果能注意一些细节无疑能在面试中加分。比如我在上面的代码中做了如下的工作: ? 用模板类实现。如果别人的

19、元素类型只是 int 类型,模板将能给面试官带来好印象; ? 两个版本的 top函数。在很多类中,都需要提供 const 和非 const 版本的成员访问函数; ? min 函数中 assert。把代码写的尽量安全是每个软件公司对程序员的要求; ? 添加一些注释。注释既能提高代码的可读性,又能增加代码量,何乐而不为? 总之,在面试时如果时间允许,尽量把代码写的漂亮一些。说不定代码中的几个小亮点就能让自己轻松拿到心仪的 Offer。)解析:3.输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为 O(n

20、)。例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,因此输出为该子数组的和 18。(分数:2.00)_正确答案:(正确答案:如果不考虑时间复杂度,我们可以枚举出所有子数组并求出他们的和。不过非常遗憾的是,由于长度为 n 的数组有 O(n2)个子数组;而且求一个长度为 n 的数组的和的时间复杂度为 O(n)。因此这种思路的时间是 O(n3)。 很容易理解,当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和

21、。基于这样的思路,我们可以写出如下代码。 参考代码: / / Find the greatest sum of all sub-arrays / Return value: if the input is valid, return true, otherwise return false / bool FindGreatestSumOfSubArray ( int *pData, / an array unsigned int nLength, / the length of array int int nCurSum = nGreatestSum = 0; for(unsigned int

22、 i = 0; i nGreatestSum) nGreatestSum = nCurSum; / if all data are negative, find the greatest element in the array if(nGreatestSum = 0) nGreatestSum = pData0; for(unsigned int i = 1; i nGreatestSum) nGreatestSum = pDatai; return true; 讨论:上述代码中有两点值得和大家讨论一下: ? 函数的返回值不是子数组和的最大值,而是一个判断输入是否有效的标志。如果函数返回值的

23、是子数组和的最大值,那么当输入一个空指针是应该返回什么呢?返回 0?那这个函数的用户怎么区分输入无效和子数组和的最大值刚好是 0 这两中情况呢?基于这个考虑,本人认为把子数组和的最大值以引用的方式放到参数列表中,同时让函数返回一个函数是否正常执行的标志。 ? 输入有一类特殊情况需要特殊处理。当输入数组中所有整数都是负数时,子数组和的最大值就是数组中的最大元素。)解析:4.输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如输入整数 22 和如下二元树 10 / 5 12 / 4 7 则打印出两条路径:10, 12 和

24、 10, 5, 7。二元树结点的数据结构定义为:struct BinaryTreeNode / a node in the binary tree int m_nValue; / value of node BinaryTreeNode *m_pLeft; / left child of node BinaryTreeNode *m_pRight; / right child of node;(分数:2.00)_正确答案:(正确答案:当访问到某一结点时,把该结点添加到路径上,并累加当前结点的值。如果当前结点为叶结点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,我们把它打印出来。如果

25、当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到父结点。因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父结点时路径刚好是根结点到父结点的路径。我们不难看出保存路径的数据结构实际上是一个栈结构,因为路径要与递归调用状态一致,而递归调用本质就是一个压栈和出栈的过程。 参考代码: / / Find paths whose sum equal to expected sum / void FindPath ( BinaryTreeNode* pTreeNode, / a node of binary tree int expectedSum,

26、 / the expected sum std:vector currentSum += pTreeNode-m_nValue; path.push_back(pTreeNode-m_nValue); / if the node is a leaf, and the sum is same as pre-defined, / the path is what we want. print the path bool isLeaf = (!pTreeNode-m_pLeft if(currentSum = expectedSum for(; iter != path.end(); + iter)

27、 std:coutm_pLeft, expectedSum, path, currentSum); if(pTreeNode-m_pRight) FindPath(pTreeNode-m_pRight, expectedSum, path, currentSum); / when we finish visiting a node and return to its parent node, / we should delete this node from the path and / minus the nodes value from the current sum currentSum -= pTreeNode-m_nValue; /!I think here is no use path.pop_back(); )解析:

copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1