二叉树面试题之三

对于二叉树的其他操作,参考前面两篇文章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;
}

结果如下所示:
这里写图片描述

以上内容就是二叉树中一些常问道的面试题,希望对大家有帮助!!有错误的地方,还请大家指教!!!

只有不停的奔跑,才能不停留在原地!!!

(1)非递归定义 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除结点外n0 , 其余的每一个结点都有且仅有一个直接前驱结点;有零个或多个直接后继结点。 (2)递归定义 一颗大树分成几个大的分枝,每个大分枝再分成几个小分枝,小分枝再分成更小的分枝,… ,每个分枝也都是一颗树,由此我们可以给出树的递归定义。 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除根结点之外的其他结点分为m(m≥0)个互不相交的集合T0,T1,…,Tm-1,其中每个集合Ti(0≤i<m)本身又是一棵树,称为根的子树(subtree)。 2、掌握树的各种术语: (1) 父母、孩子与兄弟结点 (2) 度 (3) 结点次、树的高度 (4) 边、路径 (5) 无序树、有序树 (6) 森林 3、二叉树的定义 二叉树(binary tree)是由n(n≥0)个结点组成的有限集合,此集合或者为空,或者由一个结点加上两棵分别称为左、右子树的,互不相交的二叉树组成。 二叉树可以为空集,因此根可以有空的左子树或者右子树,亦或者左、右子树皆为空。 4、掌握二叉树的五个性质 5、二叉树的二叉链表存储。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值