面试类二叉树题目汇总
来源:互联网 发布:淘宝一件代发是真的吗 编辑:程序博客网 时间:2024/06/05 17:16
目录:
1 求二叉树节点个数2.1 求二叉树的深度
2.2 判断二叉树是否是平衡树
3 二叉树转化为双向链表
4 二叉树的镜像
5 输入一行整数,判断是不是二叉搜索树的后序遍历?假设输入的任意两个数字均不相同。
6 二叉树中和为某一值的路径。
7 数中两个结点的公共祖先之求从根节点分别到某个节点的路径。
8 输入两棵二叉树A和B, 判断B是不是A的子结构。
9.1递归前中后遍历二叉树
9.2 非递归前中后遍历二叉树
9.3 二叉树DFS BFS
10 求二叉树第K层节点个数
11 求二叉树叶结点个数
12 求二叉树中节点的最大距离
13判断一棵树是否是完全二叉树
14 重建二叉树(剑指offr T6)
struct BinaryTreeNode
{int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
1 求二叉树节点个数
{
if (pRoot == NULL)
return 0;
else
return (GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1);
}
2.1 求二叉树的深度
{
if (pRoot == NULL)
return 0;
int nLeft = TreeDepth(pRoot->m_pLeft);
int nRight = TreeDepth(pRoot->m_pRight);
return (nLeft > nRight) ? (nLeft + 1) : (nRight+1);
}
2.2 判断二叉树是否是平衡树
方法1
bool IsBalanced(BinaryTreeNode *pRoot)
{
if (pRoot == NULL)
return true;
int Left = TreeDepth(pRoot->m_pLeft);
int Right = TreeDepth(pRoot->m_pRight);
int diff = Left - Right;
if (diff < -1 || diff > 1)
return false;
return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight);
}
方法2
bool IsBalanced1(BinaryTreeNode *pRoot, int &len)
{
if (pRoot == NULL)
{
len = 0;
return true;
}
int left, right;
if (IsBalanced1(pRoot->m_pLeft, left) && IsBalanced1(pRoot->m_pRight, right))
{
int diff = left - right;
if (diff >= -1 && diff <= 1)
{
len = (left > right) ? (left + 1) : (right + 1);
return true;
}
}
return false;
}
3 二叉树转化为双向链表
方法1
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);
}
方法2
BinaryTreeNode *Tmp = NULL;
BinaryTreeNode *Calc2(BinaryTreeNode *pNode)
{
if (pNode == NULL)
return NULL;
BinaryTreeNode *pCurr = pNode;
if (pCurr->m_pLeft != NULL)
{
Tmp = Calc2(pCurr->m_pLeft);
}
pCurr->m_pLeft = Tmp;
if (Tmp != NULL)
Tmp->m_pRight = pCurr;
Tmp = pCurr;
if (pCurr->m_pRight != NULL)
{
Tmp = Calc2(pCurr->m_pRight);
}
return Tmp;
}
BinaryTreeNode * Convert(BinaryTreeNode *pRoot)
{
BinaryTreeNode *Tmp1 = Calc2(pRoot);
while (Tmp1 != NULL&&Tmp1->m_pLeft != NULL)
{
Tmp1 = Tmp1->m_pLeft;
}
return Tmp1;
}
方法3
BinaryTreeNode * Calc1(BinaryTreeNode *pNode,BinaryTreeNode *pLast)
{
if (pNode == NULL)
return NULL;
BinaryTreeNode *pCurr = pNode;
if (pCurr->m_pLeft != NULL)
{
pLast=Calc1(pCurr->m_pLeft, pLast);
}
pCurr->m_pLeft = pLast;
if (pLast != NULL)
{
(pLast)->m_pRight = pCurr;
}
pLast = pCurr;
if (pCurr->m_pRight != NULL)
{
pLast=Calc1(pCurr->m_pRight, pLast);
}
return pLast;
}
BinaryTreeNode * Convert(BinaryTreeNode *pRoot)
{
BinaryTreeNode *Tmp1 = Calc1(pRoot,NULL);
while (Tmp1 != NULL&&Tmp1->m_pLeft != NULL)
{
Tmp1 = Tmp1->m_pLeft;
}
return Tmp1;
}
4 二叉树的镜像
方法1 循环实现,循环实现肯定要用stack喽
void MirrorIteratively(BinaryTreeNode* pRoot)
{
if(pRoot == NULL)
return;
std::stack<BinaryTreeNode*> stackTreeNode;
stackTreeNode.push(pRoot);
while(stackTreeNode.size() > 0)
{
BinaryTreeNode *pNode = stackTreeNode.top();
stackTreeNode.pop();
BinaryTreeNode *pTemp = pNode->m_pLeft;
pNode->m_pLeft = pNode->m_pRight;
pNode->m_pRight = pTemp;
if(pNode->m_pLeft)
stackTreeNode.push(pNode->m_pLeft);
if(pNode->m_pRight)
stackTreeNode.push(pNode->m_pRight);
}
}
方法2 递归实现!
void MirrorRecursively(BinaryTreeNode *pNode)
{
if((pNode == NULL) || (pNode->m_pLeft == NULL && pNode->m_pRight))
return;
BinaryTreeNode *pTemp = pNode->m_pLeft;
pNode->m_pLeft = pNode->m_pRight;
pNode->m_pRight = pTemp;
if(pNode->m_pLeft)
MirrorRecursively(pNode->m_pLeft);
if(pNode->m_pRight)
MirrorRecursively(pNode->m_pRight);
}
5 输入一行整数,判断是不是二叉搜索树的后序遍历?假设输入的任意两个数字均不相同。
bool VerifySquenceOfBST(int sequence[], int length)
{
if(sequence == NULL || length <= 0)
return false;
int root = sequence[length - 1];
// 在二叉搜索树中左子树的结点小于根结点
int i = 0;
for(; i < length - 1; ++ i)
{
if(sequence[i] > root)
break;
}
// 在二叉搜索树中右子树的结点大于根结点
int j = i;
for(; j < length - 1; ++ j)
{
if(sequence[j] < root)
return false;
}
// 判断左子树是不是二叉搜索树
bool left = true;
if(i > 0)
left = VerifySquenceOfBST(sequence, i);
// 判断右子树是不是二叉搜索树
bool right = true;
if(i < length - 1)
right = VerifySquenceOfBST(sequence + i, length - i - 1);
return (left && right);
}
6 二叉树中和为某一值的路径。
输入一棵二叉树和一个整数,打印出二叉树中和为此输入值的所有路径。从根节点到叶结点形成一条完整路径。
void FindPath(BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum);
void FindPath(BinaryTreeNode* pRoot, int expectedSum)
{
if(pRoot == NULL)
return;
std::vector<int> path;
int currentSum = 0;
FindPath(pRoot, expectedSum, path, currentSum);
}
void FindPath
(
BinaryTreeNode* pRoot,
int expectedSum,
std::vector<int>& path,
int& currentSum
)
{
currentSum += pRoot->m_nValue;
path.push_back(pRoot->m_nValue);
// 如果是叶结点,并且路径上结点的和等于输入的值
// 打印出这条路径
bool isLeaf = pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL;
if(currentSum == expectedSum && isLeaf)
{
printf("A path is found: ");
std::vector<int>::iterator iter = path.begin();
for(; iter != path.end(); ++ iter)
printf("%d\t", *iter);
printf("\n");
}
// 如果不是叶结点,则遍历它的子结点
if(pRoot->m_pLeft != NULL)
FindPath(pRoot->m_pLeft, expectedSum, path, currentSum);
if(pRoot->m_pRight != NULL)
FindPath(pRoot->m_pRight, expectedSum, path, currentSum);
// 在返回到父结点之前,在路径上删除当前结点,
// 并在currentSum中减去当前结点的值
currentSum -= pRoot->m_nValue;
path.pop_back();
}
7 数中两个结点的公共祖先之求从根节点分别到某个节点的路径。
bool GetNodePath(TreeNode* pRoot, TreeNode* pNode, list<TreeNode*>& path)
{
if(pRoot == pNode)
return true;
path.push_back(pRoot);
bool found = false;
vector<TreeNode*>::iterator i = pRoot->m_vChildren.begin();
while(!found && i < pRoot->m_vChildren.end())
{
found = GetNodePath(*i, pNode, path);
++i;
}
if(!found)
path.pop_back();
return found;
}
8 输入两棵二叉树A和B, 判断B是不是A的子结构。
方法1
bool HasSubtreeCore(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
bool result = false;
if(pRoot1 != NULL && pRoot2 != NULL)
{
if(pRoot1->m_nValue == pRoot2->m_nValue)
result = DoesTree1HaveTree2(pRoot1, pRoot2);
if(!result)
result = HasSubtree(pRoot1->m_pLeft, pRoot2);
if(!result)
result = HasSubtree(pRoot1->m_pRight, pRoot2);
}
return result;
}
bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
if(pRoot2 == NULL)
return true;
if(pRoot1 == NULL)
return false;
if(pRoot1->m_nValue != pRoot2->m_nValue)
return false;
return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) &&DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
}
方法2
bool DoesTree1HasTree2(BinaryTreeNode *pRoot1, BinaryTreeNode *pRoot2);
bool HasSubtree(BinaryTreeNode *pRoot1, BinaryTreeNode *pRoot2)
{
if (pRoot1 == NULL || pRoot2 == NULL)
{
return false;
}
else if (pRoot1 != NULL&&pRoot2 != NULL)
{
if (pRoot1->m_nValue == pRoot2->m_nValue)
{
if (DoesTree1HasTree2(pRoot1, pRoot2))
return true;
else
return HasSubtree(pRoot1->m_pLeft, pRoot2) || HasSubtree(pRoot1->m_pRight, pRoot2);
}
else if (pRoot1->m_nValue != pRoot2->m_nValue)
{
return HasSubtree(pRoot1->m_pLeft, pRoot2) || HasSubtree(pRoot1->m_pRight, pRoot2);
}
}
}
bool DoesTree1HasTree2(BinaryTreeNode *pRoot1, BinaryTreeNode *pRoot2)
{
if (pRoot2 == NULL)
return true;
else if (pRoot1 == NULL)
return false;
else if (pRoot1 != NULL&&pRoot2 != NULL)
{
if (pRoot1->m_nValue == pRoot2->m_nValue)
return DoesTree1HasTree2(pRoot1->m_pRight, pRoot2->m_pRight) && DoesTree1HasTree2(pRoot1->m_pLeft, pRoot2->m_pLeft);
else
return false;
}
}
9.1递归前中后遍历二叉树
9.2 非递归前中后遍历二叉树
9.3 二叉树DFS BFS
10 求二叉树第K层节点个数
int GetNumOfK(BinaryTreeNode *pRoot, int k, int level)
{
if (pRoot == NULL)
return 0;
static int num = 0;
if (level == k)
{
num++;
return num;
}
GetNumOfK(pRoot->m_pLeft, k, level + 1);
GetNumOfK(pRoot->m_pRight, k, level + 1);
return num;
}
11 求二叉树叶结点个数
方法1
int num = 0;
void FindLeafNum1(BinaryTreeNode *pRoot, int &num)
{
if (pRoot == NULL)
num=0;
if (pRoot->m_pLeft != NULL)
FindLeafNum1(pRoot->m_pLeft, num);
if (pRoot->m_pRight != NULL)
FindLeafNum1(pRoot->m_pRight, num);
if (pRoot->m_pLeft == NULL&&pRoot->m_pRight == NULL)
{
num++;
}
}
方法2
int FindLeafNum(BinaryTreeNode *pRoot)
{
if (pRoot == NULL)
return 0;
if (pRoot->m_pLeft == NULL&&pRoot->m_pRight == NULL)
return 1;
return FindLeafNum(pRoot->m_pRight) + FindLeafNum(pRoot->m_pLeft);
}
方法3 也可以用全局变量
int FindLeafNum2(BinaryTreeNode *pRoot)
{
static int num = 0;
if (pRoot == NULL)
num = 0;
if (pRoot->m_pLeft == NULL&&pRoot->m_pRight == NULL)
{
num++;
}
if (pRoot->m_pLeft != NULL)
FindLeafNum2(pRoot->m_pLeft);
if (pRoot->m_pRight != NULL)
FindLeafNum2(pRoot->m_pRight);
return num;
}
12 求二叉树中节点的最大距离
int GetFarDistance(BinaryTreeNode *pRoot, int &distance)//函数返回的是当前节点左边最大距离和右边最大距离较大的一个,包括本节点;而distance代表的是以此节点为头结点树的两子节点最大距离;
{
if (!pRoot)
return 0;
int left = GetFarDistance(pRoot->m_pLeft, distance);
int right = GetFarDistance(pRoot->m_pRight, distance);
if ((left + right) > distance)
distance = (left + right);
return left > right ? left + 1 : right + 1;
}
int GetFarDistance(BinaryTreeNode *pRoot)
{
if (!pRoot)
return 0;
int distance = 0;
GetFarDistance(pRoot, distance);
return distance;
}
13判断一棵树是否是完全二叉树
{
if (pRoot == NULL)
return false;
queue<BinaryTreeNode *> q;
q.push(pRoot);
int flag = 0;//flag代表之前的遍历中是否出现过缺少子节点的情况!
while (!q.empty())
{
BinaryTreeNode *curr = q.front();
q.pop();
if (curr->m_pLeft)
{
if (flag)
return false;
else
q.push(curr->m_pLeft);
}
else
{
if (flag==0)
flag = 1;
}
if (curr->m_pRight)
{
if (flag)
return false;
else
q.push(curr->m_pRight);
}
else
{
if (flag == 0)
flag = 1;
}
}
return true;
}
14 重建二叉树(剑指offr T6)
根据前序和中序重建二叉树,假设没有重复数字。
BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder);
BinaryTreeNode* Construct(int* preorder, int* inorder, int length)
{
if(preorder == NULL || inorder == NULL || length <= 0)
return NULL;
return ConstructCore(preorder, preorder + length - 1,
inorder, inorder + length - 1);
}
BinaryTreeNode* ConstructCore
(
int* startPreorder, int* endPreorder,
int* startInorder, int* endInorder
)
{
// 前序遍历序列的第一个数字是根结点的值
int rootValue = startPreorder[0];
BinaryTreeNode* root = new BinaryTreeNode();
root->m_nValue = rootValue;
root->m_pLeft = root->m_pRight = NULL;
if(startPreorder == endPreorder)
{
if(startInorder == endInorder && *startPreorder == *startInorder)
return root;
else
throw std::exception("Invalid input.");
}
// 在中序遍历中找到根结点的值
int* rootInorder = startInorder;
while(rootInorder <= endInorder && *rootInorder != rootValue)
++ rootInorder;
if(rootInorder == endInorder && *rootInorder != rootValue)
throw std::exception("Invalid input.");
int leftLength = rootInorder - startInorder;
int* leftPreorderEnd = startPreorder + leftLength;
if(leftLength > 0)
{
// 构建左子树
root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd,
startInorder, rootInorder - 1);
}
if(leftLength < endPreorder - startPreorder)
{
// 构建右子树
root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,
rootInorder + 1, endInorder);
}
return root;
}
- 面试类二叉树题目汇总
- java面试中的二叉树题目汇总
- 面试准备系列03----面试中的二叉树题目汇总
- 二叉查找树的典型面试题目汇总
- 二叉查找树的典型面试题目汇总
- 二叉树题目汇总
- 二叉树 面试题目
- 面试中的二叉树题目
- 面试题目集锦--二叉树
- 面试中的二叉树题目
- 面试中的二叉树题目
- 面试中的二叉树题目
- 面试中的二叉树题目
- 面试中的二叉树题目
- .net面试题目汇总
- java面试题目汇总
- Java面试题目汇总
- 面试题目汇总
- Linux内核:基于int指令的经典系统调用过程分析
- java7新版文件操作
- docker、镜像与集装箱
- 距离度量方式(马氏距离,欧式距离,曼哈顿距离)
- C语言mysql.h简单解析
- 面试类二叉树题目汇总
- 【1701H1】【穆晨】【171021】连续第十一天总结
- Xtrabackup原理及使用innobackupex进行MySQL数据库备份恢复
- 1048. 数字加密(20)
- Linux磁盘操作
- The Matrix Cookbook(译)二
- 设计模式之外观模式
- 357. Count Numbers with Unique Digits
- Rhyme/ Linux 文件系统常用命令 光盘的挂载与卸载命令