对于二叉树的其他操作,参考前面两篇文章http://blog.youkuaiyun.com/aaronlanni/article/details/78698559 http://blog.youkuaiyun.com/aaronlanni/article/details/79317946
今天,在介绍一下二叉树中一些其他的内容,详情请看下面
一、判断一个结点是否在二叉树中
在此处,判断一个结点是否在二叉树中,利用结点中的值域来进行判断
思路
(1)递归
空树—–>不在
是否为根节点—–>是—–>返回根节点
不是—–>递归在左子树中查找
不是—–>递归在右子树中查找
具体代码实现如下所示:
封装前
pNode FindNode(const T&data)
{
pNode pCur = _FindNode(_pRoot, data);
return pCur;
}
封装后
pNode _FindNode(pNode pRoot, const T &data)
{
if (NULL == pRoot)
return NULL;
if (data == pRoot->_data)
return pRoot;
pNode Ret = NULL;
if (Ret = _FindNode(pRoot->_pLeft, data))
return Ret;
return _FindNode(pRoot->_pRight,data);
}
(2)非递归
空树—–>不在
非空树—–>利用队列—–>取队头结点与当前结点比较—–>是—->返回这个结点
不是—–>如果队头结点的左右孩子存在—–>压入到队列中—–>重复以上过程,直到队列为空即可
具有代码实现如下所示:
pNode _FindNode_Nor(pNode pRoot, const T&data)
{
if (NULL == pRoot)
return NULL;
queue<pNode> q;
q.push(pRoot);
pNode pCur = NULL;
while (!q.empty())
{
pCur = q.front();
if (data == pCur->_data)
return pCur;
q.pop();
if (pCur->_pLeft)
q.push(pCur->_pLeft);
if (pCur->_pRight)
q.push(pCur->_pRight);
}
return NULL;
}
测试代码如下:
void TestTree()
{
//利用数组
char array[] = "abd###ce##f";
BindaryTree<char> bt(array, strlen(array), '#');
//查找一个结点是否在树中
//结点在树中
BindaryTreeNode<char> * pos = bt.FindNode('a');
if (pos)
cout << "找到了" << pos->_data << endl;
else
cout << "没找到" << endl;
BindaryTreeNode<char> * pos_1 = bt.FindNode_Nor('a');
if (pos_1)
cout << "找到了" << pos_1->_data << endl;
else
cout << "没找到" << endl;
////结点没有在树中
BindaryTreeNode<char> * pos1 = bt.FindNode('h');
if (pos1)
cout << "找到了" << pos1->_data << endl;
else
cout << "没找到" << endl;
BindaryTreeNode<char> * pos1_1 = bt.FindNode_Nor('h');
if (pos1_1)
cout << "找到了" << pos1_1->_data << endl;
else
cout << "没找到" << endl;
//空树
BindaryTree<char> bt3;
BindaryTreeNode<char> * pos2 = bt3.FindNode('a');
if (pos2)
cout << "找到了" <<pos2->_data<< endl;
else
cout << "没找到" << endl;
BindaryTreeNode<char> * pos2_1 = bt3.FindNode_Nor('a');
if (pos2_1)
cout << "找到了" << pos2_1->_data << endl;
else
cout << "没找到" << endl;
}
结果如下所示:
二、求一棵二叉树的镜像
二叉树的镜像
镜像,顾名思义,就是对着镜子照出另一种形式即可,在这里,采用两种形式,分别为递归和非递归
(1)递归
空树—–>直接返回
多个结点—–>先交换根节点的左右孩子,在利用递归,交换根节点的左子树,其次交换根节点的右子树即可
具体代码实现如下所示:
void _Mirror(pNode pRoot)
{
if (NULL == pRoot)
return;
if (pRoot)
{
swap(pRoot->_pLeft, pRoot->_pRight);
_Mirror(pRoot->_pLeft);
_Mirror(pRoot->_pRight);
}
}
(2)非递归
空树—–>直接返回
多个结点—–>先将根节点压入到队列中,取队列中的队头元素,交换队头元素的左右孩子,交换完成之后,将队头元素弹出,利用刚才标记的队头元素,如果此结点的左右孩子存在,将此结点的左右孩子压入到队列中,一直重复上面的取队头,交换,压入的过程,直到队列为空即可。
具有代码实现如下所示:
void _Mirror_Nor(pNode pRoot)
{
if (NULL == pRoot)
return;
queue<pNode> q;
q.push(pRoot);
pNode pCur = NULL;
while (!q.empty())
{
pCur = q.front();
swap(pCur->_pLeft, pCur->_pRight);
q.pop();
if (pCur->_pLeft)
q.push(pCur->_pLeft);
if (pCur->_pRight)
q.push(pCur->_pRight);
}
}
测试代码如下:
void TestTree()
{
//利用数组
char array[] = "abd###ce##f";
BindaryTree<char> bt(array, strlen(array), '#');
cout << "@非空树" << endl;
bt.Mirror();
bt.FrontOrder();
bt.Mirror_Nor();
bt.FrontOrder();
//空树
BindaryTree<char> bt3;
cout << "@空树" << endl;
bt3.Mirror();
bt3.FrontOrder();
bt3.Mirror_Nor();
bt3.FrontOrder();
}
结果如下所示
三、求二叉树中,第K层结点的个数
K<0或者K 的值大于树的高度或者树为空—–>返回0
K=1—–>返回1
K>2—–>利用递归,左子树中第K层结点的个数+右子树中第K层结点的个数
这里,有关树的高度,在前判断一个二叉树是否是平衡树中已经给出,详情参参考上面http://blog.youkuaiyun.com/aaronlanni/article/details/79317946
具体代码实现如下所示:
size_t _TheKCount(pNode pRoot, int K)
{
if (K < 0 || K > Height() || pRoot == NULL)
return 0;
if (1 == K)
return 1;
int Left = _TheKCount(pRoot->_pLeft, K - 1);
int Right = _TheKCount(pRoot->_pRight, K - 1);
return Left + Right;
}
测试代码如下所示:
void TestTree()
{
//利用数组
char array[] = "abd###ce##f";
BindaryTree<char> bt(array, strlen(array), '#');
//K在树中,
cout << "K在树中" << endl;
cout << "第3层,TheKCount=" << bt.TheKCount(3) << endl;
/*K小于0*/
cout << "K小于0" << endl;
cout << "第-2层,TheKCount=" << bt.TheKCount(-2) << endl;
//K大于树的高度,
cout << "K大于树的高度" << endl;
cout << "第4层,TheKCount=" << bt.TheKCount(4) << endl;
}
结果如下所示:
四、求叶子结点的个数
叶子结点,即没有左孩子与右孩子的结点
算法:空树—–>直接返回0
树中只有一个结点—–>返回1
多个结点—–>利用递归,左子树中叶子结点的个数+右子树中叶子结点的个数
具体代码实现如下所示:
封装前
size_t LeafCount()
{
int count = 0;
count = _LeafCount(_pRoot);
return count;
}
封装后
size_t _LeafCount(pNode pRoot)
{
if (NULL == pRoot)
return 0;
if (pRoot->_pLeft == NULL&&pRoot->_pRight == NULL)
return 1;
return _LeafCount(pRoot->_pLeft) + _LeafCount(pRoot->_pRight);
}
测试代码如下所示
void TestTree()
{
//利用数组
char array[] = "abd###ce##f";
BindaryTree<char> bt(array, strlen(array), '#');
cout << "非空树,多个结点" << endl;
cout << "LeafCount=" << bt.LeafCount() << endl;
char array1[] = "a";
BindaryTree<char> bt2(array1, strlen(array1), '#');
cout << "非空树,一个结点" << endl;
cout << "LeafCount=" << bt2.LeafCount() << endl;
BindaryTree<char> bt3;
cout << "空树" << endl;
cout << "LeafCount=" << bt3.LeafCount() << endl;
}
结果如下所示:
以上内容就是二叉树中一些常问道的面试题,希望对大家有帮助!!有错误的地方,还请大家指教!!!
只有不停的奔跑,才能不停留在原地!!!