赞
踩
目录
二、int sizeOf(TreeNode root) :获取树中结点个数
三、 int leafSizeOf(TreeNode root) :获取叶子结点的个数
1. 使用打包的方式: class TreeNodeWithLevel
2. 使用两个队列:nodeQueue 和 levelQueue
五、int getKLevelSize(TreeNode root , int k) :获取第 k 层结点的个数
六、int heightOf(TreeNode root) :获取二叉树的高度
七、boolean isCompleteTree(TreeNode root):判断一棵树是否是完全二叉树
凡是广度优先遍历,都要用到队列。使用队列确保先进先出(FIFO)。
层序遍历要求从上往下(每个结点负责其孩子),从左往右(先左子树再右子树)。取出一个元素,就把其相应的左右孩子放入队列中(null 的不用放入)。
代码:
- public static void levelorder(TreeNode root) {
- if (root == null) {
- return;
- }
- Queue<TreeNode> queue = new LinkedList<>();
- //先将根结点放入,再进行循环判断
- //1. 取出队首元素
- //2. 打印队首元素值
- //3. 将队首元素的左孩子和右孩子依次放入队列中,为 null 的结点不放入
- queue.offer(root);
- while (!queue.isEmpty()) {
- TreeNode p = queue.poll();
- System.out.println(p.toString());
- if (p.left != null) {
- queue.offer(p.left);
- }
- if (p.right != null) {
- queue.offer(p.right);
- }
- }
- }
思路:层序遍历,利用队列,每取出一个元素,size++
代码:
- public static int sizeOf(TreeNode root) {
- if (root == null) {
- return 0;
- }
- Queue<TreeNode> queue = new LinkedList<>();
- queue.offer(root);
- int size = 0;
- while (!queue.isEmpty()) {
- TreeNode p = queue.poll();
- size++;
- if (p.left != null) {
- queue.offer(p.left);
- }
- if (p.right != null) {
- queue.offer(p.right);
- }
- }
- return size;
- }
思路:跟统计结点数类似,只有当是叶子结点时,size 才进行 +1
代码:
- public static int leafSizeOf(TreeNode root) {
- if (root == null) {
- return 0;
- }
- Queue<TreeNode> queue = new LinkedList<>();
- queue.offer(root);
- int size = 0;
- while (!queue.isEmpty()) {
- TreeNode p = queue.poll();
- if (p.left == null && p.right == null) {
- size++;
- }
- if (p.left != null) {
- queue.offer(p.left);
- }
- if (p.right != null) {
- queue.offer(p.right);
- }
- }
- return size;
- }
使用打包的方式,新建一个类,将结点和该结点相应的层数作为属性放入该类中。使用是将TreeNode 替换成 TreeNodeWithLevel,并且向队列中添加元素时,传入结点的同时,传入 level 层数即可。(若 node 的层数为 level,那么 node 的左右孩子的层数就为 level + 1)
代码:
- static class TreeNodeWithLevel {
- public TreeNode node;
- public int level;
-
- public TreeNodeWithLevel(TreeNode node, int level) {
- this.node = node;
- this.level = level;
- }
-
- @Override
- public String toString() {
- return String.format("%s-%d",node.toString(),level);
- }
- }
-
- //层序遍历 (带层数)
- public static void levelorderWithLevel(TreeNode root) {
- if (root == null) {
- return;
- }
- Queue<TreeNodeWithLevel> queue = new LinkedList<>();
- queue.offer(new TreeNodeWithLevel(root,1));
- while (!queue.isEmpty()) {
- TreeNodeWithLevel node = queue.poll();
- TreeNode p = node.node;
- int level = node.level;
- System.out.println(node);
- if (p.left != null) {
- queue.offer(new TreeNodeWithLevel(p.left,level + 1));
- }
- if (p.right != null) {
- queue.offer(new TreeNodeWithLevel(p.right,level + 1));
- }
-
- }
- }
使用两个队列,一个队列存放结点,另一个队列存放相应的层数。需要注意的是两个队列对应的元素个数一样,所以在 while() 条件判断时,取任意一个队列的元素不为空即可。
代码:
- public static void levelorderWithLevel2(TreeNode root) {
- if (root == null) {
- return;
- }
- Queue<TreeNode> nodeQueue = new LinkedList<>();
- Queue<Integer> levelQueue = new LinkedList<>();
-
- nodeQueue.offer(root);
- levelQueue.offer(1);
-
- while (!nodeQueue.isEmpty()) {
- TreeNode p = nodeQueue.poll();
- int level = levelQueue.poll();
- System.out.println( p + " + " + level);
-
- if (p.left != null) {
- nodeQueue.offer(p.left);
- levelQueue.offer(level + 1);
- }
- if (p.right != null) {
- nodeQueue.offer(p.right);
- levelQueue.offer(level + 1);
- }
- }
- }
思路:使用带层数的层序遍历,当从队列中取出的元素的 level == k 时,size++。
代码:
- public static int getKLevelSize(TreeNode root,int k) {
- if (root == null) {
- return 0;
- }
-
- Queue<TreeNodeWithLevel> queue = new LinkedList<>();
- queue.offer(new TreeNodeWithLevel(root,1));
-
- //定义变量,记录 k 层结点的个数
- int size = 0;
- while (!queue.isEmpty()) {
- TreeNodeWithLevel node = queue.poll();
- TreeNode p = node.node;
- int level = node.level;
-
- if (level == k) {
- //说明是第 k 层了
- size++;
- }
- if (p.left != null) {
- queue.offer(new TreeNodeWithLevel(p.left,level + 1));
- }
- if (p.right != null) {
- queue.offer(new TreeNodeWithLevel(p.right,level + 1));
- }
- }
- return size;
- }
思路:使用带层数的层序遍历,返回最后一个加入队列结点的 level 值即可。
代码:
- public static int heightOf(TreeNode root) {
- if (root == null) {
- return 0;
- }
- Queue<TreeNodeWithLevel> queue = new LinkedList<>();
- queue.offer(new TreeNodeWithLevel(root,1));
-
- //定义一个变量记录 height
- //height 的值可以根据 level 确定
- int height = -1;
- while (!queue.isEmpty()) {
- TreeNodeWithLevel node = queue.poll();
- TreeNode p = node.node;
- int level = node.level;
-
- height = level;
-
- if (p.left != null) {
- queue.offer(new TreeNodeWithLevel(p.left,level + 1));
- }
- if (p.right != null) {
- queue.offer(new TreeNodeWithLevel(p.right,level + 1));
- }
-
- }
- //此时 height 就为最后一个 level ,即最大的 level
- return height;
- }
思路:将所有元素依次加入队列,当取出的元素为 null 时停止元素添加。因为二叉树碰到 null 有两种情况:
代码:
- public static boolean isCompleteTree(TreeNode root) {
- if (root == null) {
- return true;
- }
- Queue<TreeNode> queue = new LinkedList<>();
- queue.offer(root);
-
- //循环终止的条件,从队列中取出的元素是 null
- while (true) {
- TreeNode p = queue.poll();
- if (p == null) {
- break;
- }
- //因为这里需要根据本身的树进行判断,所以不用再判断左右孩子是否为 null
- queue.offer(p.left);
- queue.offer(p.right);
- }
-
- //判断取出元素为 null 后,其后面是否还有元素,即判断后面元素是否 == null
- //当后面元素存在 != null 时,说明不是完全二叉树,返回 false
- //当后面元素都 == null 时,说明是完全二叉树,返回 true
- while (!queue.isEmpty()) {
- TreeNode q = queue.poll();
- if (q != null) {
- return false;
- }
- }
- return true;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。