分层次遍历二叉树

1.递归的方法

  二叉树本身就带有递归属性,通常我们可以用递归方法解决。假设要访问第k层节点,那么其实可以转皇城分别访问“以该二叉树根节点的左右子节点为根节点的两棵子树”中层次为k-1的节点。此方法需要求出二叉树的深度,其实可以直接访问到二叉树某一层次失败的时候返回就可以了。

  这个方法的问题是递归调用,效率较低。而且对每一层的访问都需要从根节点开始,效率极差。

  最坏的情况下(不平衡树)时间复杂度为O(n^2),空间复杂度O(1)

//输出以root为根节点中的第level层中的所有节点(从左至右),成功返回1
//失败返回0
//root为二叉树根节点
//level为层次数,其中根节点为第0层
int PrintNodeAtLevel(TreeNode *root, int level) {
    if (!root || level < 0) return 0;
    if (level == 0){
        cout<<root->val;
        return 1;
    }

    return PrintNodeAtLevel(root->left, level - 1) + PrintNodeAtLevel(root->right, level - 1);
}

//层次遍历二叉树
//root,二叉树的根节点
void LevelOrder(TreeNode *root) {
    for (int level = 0; ; level++) {
        if (!PrintNodeAtLevel(root, level)) 
            break;
        cout<<endl;
    }
}

2. 使用数组和两个游标的方法

  在访问k层的时候,我们只需要知道k-1层的信息就足够了,所以在访问第k层的时候,要是能够知道k-1层的节点信息,就不再需要从根节点开始遍历了。

  根据上述分析,可以从根节点出发,依次将每一层的根节点从左往右压入一个数组,并并用一个游标cur记录当前访问的节点,另一个游标last指示当前层次的最后一个节点的下一个位置,以cur===last作为当前层次访问结束的条件,在访问某一层的同时将该层的所有节点的子节点压入数组,在访问完某一层之后,检查是否还有新的层次可以访问,直到检查完所有的层次(不再有新的节点可以访问)

  这种方法需要一个vector一直存储所有节点,空间效率较差。

  时间复杂度为O(n),空间复杂度为O(n)

void LevelOrder(TreeNode *root) {
    if (root == NULL) return;
    vector<TreeNode *> vec; //这里使用stl中的vector代替数组,可利用到
                            //其动态扩展的属性
    vec.push_back(root);
    int cur = 0, last = vec.size();
    while (cur < vec.size()) {
        last = vec.size();

        while (cur < last) {
            cout<<vec[cur]->val;
            if (vec[cur]->left) 
                vec.push_back(vec[cur]->left);
            if(vec[cur]->right)
                vec.push_back(vec[cur]->right);
            ++cur;
        }
        cout<<endl;
    }
}

以上两种方法是书上给出的方法,其实二叉树分层遍历其实就是图的广度优先遍历的一个特殊形式,只要将其稍加修改就可以了。(树是图的一种特殊形式)

第三种方法:通过一个队列进行分层遍历

public void levelorder(BinaryNode root)
{
	linkedList<BinaryNode> que = new LinkedList<BinaryNode>();
	while(root!=null)
	{
		System.out.print(p.data);
		if(p.left!=null)
			que.add(p.left);
		if(p.right!=null)
			que.add(p.right);
		p=que.poll();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值