求二叉树最宽的层有多少个节点

本文探讨了如何使用C++和Java分别通过队列和哈希映射实现计算二叉树中最宽的层的节点数量,通过实例展示了两种方法的比较和测试用例.

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哪一层的节点数最多,它就是最宽的层。

C++ 版

/*************************************************************************
	> File Name: 031.求二叉树最宽的层有多少个节点.cpp
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 二  6/21 19:45:56 2022
 ************************************************************************/

#include <iostream>
#include <queue>
#include <ctime>
#include <unordered_map>
using namespace std;


class TreeNode {
public:
    int value;
    TreeNode *left;
    TreeNode *right;

    TreeNode(int v) : value(v) {}
};

//使用有限的几个变量
int maxWidth(TreeNode *root) {
    //cout << "maxWidth" << endl;
    if (root == nullptr) return 0;

    queue<TreeNode *> que;
    que.push(root);
    
    //当前层最右的节点
    TreeNode *curEnd = root;
    //下一层最右的节点
    TreeNode *nextEnd = nullptr;

    int ans = 0;
    //当前层的节点数
    int curLevelNodeCnt = 0;
    
    //层序遍历
    while (!que.empty()) {
        TreeNode *cur = que.front();
        //cout << "cur = " << cur << endl;
        que.pop();

        if (cur->left != nullptr) {
            que.push(cur->left);
            //统计当前层的时候,为下一层做准备
            nextEnd = cur->left;
        }

        if (cur->right != nullptr) {
            que.push(cur->right);
            nextEnd = cur->right;
        }
        
        //当前层的节点数++
        curLevelNodeCnt++;
        if (cur == curEnd) {//遍历到当前层的最后一个节点
            ans = max(ans, curLevelNodeCnt);
            //开始下一层的遍历
            curLevelNodeCnt = 0;
            curEnd = nextEnd;
        }
    }
    //cout << "maxWidth end!" << endl;
    return ans;
}

//使用容器unordered_map
int maxWidthUseMap(TreeNode *root) {
    if (root == nullptr) return 0;

    queue<TreeNode *> que;
    que.push(root);
    
    //key是节点,value是在哪一层,
    unordered_map<TreeNode *, int> levelMap;
    levelMap[root] = 1;

    int curLevel = 1;
    int curLevelNodeCnt = 0;
    int ans = 0;

    while (!que.empty()) {
        TreeNode *cur = que.front();
        que.pop();

        int curNodeLevel = levelMap[cur];

        if (cur->left != nullptr) {
            levelMap[cur->left] = curNodeLevel + 1;
            que.push(cur->left);
        }

        if (cur->right != nullptr) {
            levelMap[cur->right] = curNodeLevel + 1;
            que.push(cur->right);
        }

        if (curNodeLevel == curLevel) {
            curLevelNodeCnt++;
        } else {
            ans = max(ans, curLevelNodeCnt);
            curLevel++;
            curLevelNodeCnt = 1;
        }
    }

    ans = max(ans, curLevelNodeCnt);

    return ans;
}

//For test 

TreeNode *generate(int level, int maxLevel, int maxValue) {
    if (level > maxLevel || rand() % 100 < 0.5) return nullptr;

    TreeNode *root = new TreeNode(rand() % maxValue);
    root->left = generate(level + 1, maxLevel, maxValue);
    root->right = generate(level + 1, maxLevel, maxValue);
    return root;
}

TreeNode *generateRandomBST(int maxLevel, int maxValue) {
    return generate(1, maxLevel, maxValue);
}


TreeNode  *test() {
    TreeNode *root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    root->right->left = new TreeNode(6);
    root->right->right = new TreeNode(7);
    return root;
}

int main() {
    srand(time(0));
    int maxLevel = 10;
    int maxValue = 100;
    int testTime = 1000000;
    cout << "test begin" << endl;
    for (int i = 0; i < testTime + 1; i++) {
        TreeNode *root = generateRandomBST(maxLevel, maxValue);
        //TreeNode *root = test();
        if (maxWidth(root) != maxWidthUseMap(root)) {
            cout << maxWidth(root) << ", " << maxWidthUseMap(root) << endl;
            cout << "Oops!" << endl;
            break;
        }

        if (i && i % 1000 == 0) cout << i << " cases passed!" << endl;
    }
    cout << "finish!" << endl;
    return 0;
}

Java 版

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

public class TreeMaxWidth {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

	public static int maxWidthUseMap(Node head) {
		if (head == null) {
			return 0;
		}
		Queue<Node> queue = new LinkedList<>();
		queue.add(head);
		// key 在 哪一层,value
		HashMap<Node, Integer> levelMap = new HashMap<>();
		levelMap.put(head, 1);
		int curLevel = 1; // 当前你正在统计哪一层的宽度
		int curLevelNodes = 0; // 当前层curLevel层,宽度目前是多少
		int max = 0;
		while (!queue.isEmpty()) {
			Node cur = queue.poll();
			int curNodeLevel = levelMap.get(cur);
			if (cur.left != null) {
				levelMap.put(cur.left, curNodeLevel + 1);
				queue.add(cur.left);
			}
			if (cur.right != null) {
				levelMap.put(cur.right, curNodeLevel + 1);
				queue.add(cur.right);
			}
			if (curNodeLevel == curLevel) {
				curLevelNodes++;
			} else {
				max = Math.max(max, curLevelNodes);
				curLevel++;
				curLevelNodes = 1;
			}
		}
		max = Math.max(max, curLevelNodes);
		return max;
	}

	public static int maxWidthNoMap(Node head) {
		if (head == null) {
			return 0;
		}
		Queue<Node> queue = new LinkedList<>();
		queue.add(head);
		Node curEnd = head; // 当前层,最右节点是谁
		Node nextEnd = null; // 下一层,最右节点是谁
		int max = 0;
		int curLevelNodes = 0; // 当前层的节点数
		while (!queue.isEmpty()) {
			Node cur = queue.poll();
			if (cur.left != null) {
				queue.add(cur.left);
				nextEnd = cur.left;
			}
			if (cur.right != null) {
				queue.add(cur.right);
				nextEnd = cur.right;
			}
			curLevelNodes++;
			if (cur == curEnd) {
				max = Math.max(max, curLevelNodes);
				curLevelNodes = 0;
				curEnd = nextEnd;
			}
		}
		return max;
	}

	// for test
	public static Node generateRandomBST(int maxLevel, int maxValue) {
		return generate(1, maxLevel, maxValue);
	}

	// for test
	public static Node generate(int level, int maxLevel, int maxValue) {
		if (level > maxLevel || Math.random() < 0.5) {
			return null;
		}
		Node head = new Node((int) (Math.random() * maxValue));
		head.left = generate(level + 1, maxLevel, maxValue);
		head.right = generate(level + 1, maxLevel, maxValue);
		return head;
	}

	public static void main(String[] args) {
		int maxLevel = 10;
		int maxValue = 100;
		int testTimes = 1000000;
		for (int i = 0; i < testTimes; i++) {
			Node head = generateRandomBST(maxLevel, maxValue);
			if (maxWidthUseMap(head) != maxWidthNoMap(head)) {
				System.out.println("Oops!");
			}
		}
		System.out.println("finish!");

	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值