3-18.
你查字典时用的是什么方法?
解析:
既然要和算法相关,除了随机尝试,明显应该用二分查找。
不要嫌它简单,其实这是道MS和Google用过的面试题。
3-19.
假设你有一个装满T恤衫的衣柜,如何组织这些T恤衫以便以后取衣服?
解析:
由于衣柜是线性存储,肯定要用到排序从而应用二分查找。具体到T恤衫,可以按颜色排序。
当然,如果这是个商场中的衣柜,那么还应该在同样式内部按尺码排序。
3-20.
写一个函数,找出单链表的中间结点。
解析:
比较常见,最简单的解法是用两个指针,一个每次后移1个,另一个每次后移2个,速度快的达到末尾时,慢的正好在中间。实际编写的时候注意边界条件(最好把NULL做第0个结点,考虑结点数奇偶性不要把快的指针移动出界),略。
3-21.
写一个函数判断两个二叉树是否全等。树全等包括结构相同和对应结点数据相同。
解析:
二叉树遍历的变形,只是写函数返回值时可能迷惑。可以这样写:
int compare(struct node* a, struct node* b) { // 1. both empty -> true if (a==NULL && b==NULL) return(true); // 2. both non-empty -> compare them else if (a!=NULL && b!=NULL) { return( a->data == b->data && compare(a->left, b->left) && compare(a->right, b->right) ); } // 3. one empty, one not -> false else return 0; }
3-22.
写一个把二叉搜索树转化为链表的程序。
解析:
如果允许使用额外的辅助数据结构,可以遍历树时构造链表,也可以遍历树时把结点压入队列最后出队构造。
如果不允许使用额外的存储空间,把二叉搜索树原地转化为双链表,思想还是树的递归遍历:把根的左子树和右子树分别转化为双链表,再与根相连接。只不过连接时右子树,要注意是把原先的根作为双链表末尾来连接。下面贴的代码来自于何海涛《剑指Offer》面试题27:二叉搜索树与双向链表:
void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList); BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree) { BinaryTreeNode *pLastNodeInList = NULL; ConvertNode(pRootOfTree, &pLastNodeInList); // pLastNodeInList指向双向链表的尾结点, // 我们需要返回头结点 BinaryTreeNode *pHeadOfList = pLastNodeInList; while(pHeadOfList != NULL && pHeadOfList->m_pLeft != NULL) pHeadOfList = pHeadOfList->m_pLeft; return pHeadOfList; } void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList) { if(pNode == NULL) return; BinaryTreeNode *pCurrent = pNode; if (pCurrent->m_pLeft != NULL) ConvertNode(pCurrent->m_pLeft, pLastNodeInList); pCurrent->m_pLeft = *pLastNodeInList; if(*pLastNodeInList != NULL) (*pLastNodeInList)->m_pRight = pCurrent; *pLastNodeInList = pCurrent; if (pCurrent->m_pRight != NULL) ConvertNode(pCurrent->m_pRight, pLastNodeInList); }