您的位置:首页 > 职场人生

树的面试题

2016-05-09 23:37 447 查看
简介
前面介绍过二叉树的数据结构,它的逻辑很简单,除了根结点之外每个结点只有一个父节点,除了叶结点之外所有的结点都有一个或多个子节点。父和子之间用指针连接。

二叉树有三种变量方式:

-前序遍历:根左右

-中序遍历:左根右
-后序遍历:左右根

题目1:重建二叉树
输入某二叉树的前 序遍历和中序遍历的结果,重建该二叉树

struct BinaryTreeNode//结点结构
{
int _value;
BinaryTreeNode* _left;
BinaryTreeNode* _right;

BinaryTreeNode(const int&x)
{
_value = x;
_left = NULL;
_right = NULL;
}
};

BinaryTreeNode* Construct(int * prevOrder, int *inOrder, int length)
{
if (prevOrder == NULL || inOrder == NULL || length == 0)
return;
return ConstructCore(prevOrder,prevOrder+length-1,inOrder,inOrder+length-1)
}

BinaryTreeNode*ConstructCore(int* PrevHead, int*prevTail, int*inHead, int*inTail)
{
//前序遍历的第一个节点即为根结点
BinaryTreeNode* root = new BinaryTreeNode(PrevHead[0]);
//只有一个节点
if (PrevHead == prevTail)
{
if (inHead == inTail)
return root;
else
throw std::exception("Invalid inPut");//抛出异常
}
//在中序结点中找到根结点的值
int *InorderRoot = inHead;
while (InorderRoot<=inTail&&InorderRoot != PrevHead)
{
InorderRoot++;
}
if (InorderRoot == inTail&&*InorderRoot != PrevHead[0])
throw std::exception("Invalid input");

int leftLength = InorderRoot - inHead;
int* leftPrevOrderTail = PrevHead + leftLength;
if (leftLength > 0)
{
//构建左子树
root->_left = ConstructCore(PrevHead + 1, leftPrevOrderTail, inHead, InorderRoot - 1);
}
if (leftLength < prevTail - PrevHead)
{
//构建右子树
root->_right = ConstructCore(leftPrevOrderTail + 1, prevTail, InorderRoot + 1, inTail);
}
return root;
}
题目二:二叉树的镜像
先前序遍历这棵树的结点,若遍历到的结点有子节点,就交换这个两个子节点,当交换完成所有非叶子结点的左右结点之后,就得到数的镜像
void MirrorRecursively(BinaryTreeNode *pRoot)
{
if ((pRoot == NULL)||(pRoot->m_pLeft==NULL&&pRoot->m_pRight==NULL))
return;
swap(pRoot->m_pLeft, pRoot->m_pRight);
if (pRoot->m_pLeft)
MirrorRecursively(pRoot->m_pLeft);
if (pRoot->m_pRight)
MirrorRecursively(pRoot->m_pRight);

}
题目三:输入两颗二叉树A和B,判断B不是A的子结构
bool HasSubTree(BinaryTreeNode*pRoot1, BinaryTreeNode*pRoot2)
{
BinaryTreeNode* pcur1 = pRoot1;
BinaryTreeNode* pcur2 = pRoot2;
bool result = false;
if (pRoot1 != NULL || pRoot2 != NULL)
{
if (pcur1->m_value == pcur2->m_value)
result = DoseTree1HaveTree2(pcur1, pcur2);
if (!result)
result = HasSubTree(pcur1->m_pLeft, pcur2);
if (!result)
result = HasSubTree(pcur1->m_pRight, pcur2);
}
return result;
}
bool DoseTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
if (pRoot2 == NULL)
return true;
if (pRoot2 == NULL)
return false;
if (pRoot1->m_value != pRoot2->m_value)
return false;
return DoseTree1HaveTree2(pRoot1->m_pLeft, pRoot1->m_pLeft) && DoseTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
}
题目四:层序遍历二叉树
void PrintLevelOrder(BinaryTreeNode<T>*root)
{
if (root == NULL)
return;
queue<BinaryTreeNode<T>*>q1;
q1.push(root);

while (q1.size() != 0)
{
if (q1.front()->_left)
{
q1.push(q1.front()->_left);
}
if (q1.front()->_right)
{
q1.push(q1.front()->_right);
}
cout << q1.front()->_value << " ";
q1.pop();
}
}
题目五:前序非递归实现
void PrintPrevOrder(BinaryTreeNode<T>root)
{
if(root==NULL)
return;
stack<BinaryTreeNode<T>*>s;
s.push(root);
while(s.size()>0)
{
BinaryTreeNode<T>*cur=s.top();
s.pop();
cout<<cur->_value<<" ";

if(root->_right!=NULL)
s.push(root->_right);
if(root->_left!=NULL)
s.push(root->_left);
}
}
题目六:中序的非递归实现
void PrintInOrder(BinaryTreeNode<T>root)
{
stack<BinaryTreeNode<T>*>s;
BinaryTreeNode<T>*cur=root;

while(cur||s.size>0)
{
s.push(cur);
while(cur->_left)
{
s.pusu(cur->_left);
cur=cur->_left;
}
cout<<s.top()->_value<<" ";
cur=s.top()->_right;
s.pop();
}
}
题目七:后序的非递归实现
void PrintPostOrder(BinaryTreeNode<T>*root)
{
stack<BinaryTreeNode<T>*>s;
BinaryTreeNode<T>*cur = root;
BinaryTreeNode<T>*prev = NULL;
while (cur || s.size() > 0)
{
while (cur != NULL)
{
s.push(cur);
cur = cur->_left;
}
cur = s.top();
if (cur->_right == NULL || cur->_right == prev)
{
cout << cur->_value << " ";
prev = cur;
cur = NULL;
s.pop();
}
else
{
cur = cur->_right;
}
}
}
题目八:二叉搜索树的后序遍历
输入一个整数数组,判断该数组是不是某二叉树的后序遍历结果,如果是返回true,否则返回false
bool VerifySquenceOfBST(int sequence[], int length)
{
if (sequence == NULL || length <= 0)
return false;
int root = sequence[length - 1];

size_t i = 0;
for ( i = 0; i < length - 1; i++)
{
if (sequence[i]>root)
break;
}

size_t j = i;
for (; j < length; j++)
{
if (sequence[j] < root)
return false;
}
bool left = true;
left = VerifySquenceOfBST(sequence, i);

bool right = true;
right = VerifySquenceOfBST(sequence + i, length - i - i);

return left&&right;
}
题目九:二叉树中和为某一值的路径
输入一个二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径,从树的根开始往下一直到叶形成一条路径
void Findpath(BinatryTreeNode<T>*root, T sum)
{
if (root == NULL)
return;
vector<BinatryTreeNode<T>*> path;
int curSum = 0;
_FindPath(root, sum, path, curSum);
}
private:
void _FindPath(BinatryTreeNode<T>*root, const T&sum, vector<BinaryTreeNode<T>*>&path, T&curSum)
{
curSum_ += root->_value;
path.push_back(root);
//如果为叶结点且路径值相等则输出路径
bool IsLeaf = root->_right == NULL&&root->_left == NULL;
if (curSum == sum&&IsLeaf)
{
for (size_t i = 0; i < path.size(); i++)
{
cout << path[i]->_value << " ";
}
}
//若不是叶结点遍历至叶结点
if (root->_left != NULL)
_FindPath(root->_left, sum, path, curSum);
if (root->_right != NULL)
_FindPath(root->_right, sum, path, curSum);

curSum -= root->_value;
path.pop_back();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 offer 剑指