求一顆二叉樹的最大寬度(以及寬度遍歷)


一、如何實現二叉樹的寬度遍歷

寬度遍歷用隊列(先進先出)

1)先把頭節點放入隊列中

2)每次彈出一個,打印

3)對於彈出的節點,先把彈出節點的節點放入隊列、再把其節點放入隊列(沒有左右節點就不放)

重復以上三個步驟

 

//寬度遍歷
    public static void w(Node head){
        if (head == null){
            return;
        }
        Queue<Node> queue = new LinkedList<>(); //java中,LinkedList就是隊列
        queue.add(head);
        while(!queue.isEmpty()){
            Node cur = queue.poll();
            System.out.print(cur.value);
            if (cur.left != null){
                queue.add(cur.left);
            }
            if (cur.right!= null){
                queue.add(cur.right);
            }
        }        
    }
寬度遍歷

二、求一個二叉樹的最大寬度

 思路,在寬度遍歷的基礎上進行改進:

curLevel:記錄當前Node所在層數
curWidth:記錄當前層的寬度
maxWidth:記錄全局最大層的寬度 

1、新增一個HashMap,用於記錄當前Node屬於哪一層
2、每次添加Node進隊列時,記錄當前Node所在層次
3、每次poll出一個Node時,在HashMap中獲取它屬於哪一層,如果屬於當前層,curWidth++。反之 maxWidth = Math.max(maxWidth, curWidth) , curLevel++

//獲取二叉樹中最大層的寬度
    public static int getMaxWidth(Node head) {
        if (head == null) {
            return 0;
        }
        Queue<Node> queue = new LinkedList<>(); //java中,LinkedList就是隊列
        queue.add(head);
        HashMap<Node, Integer> levelMap = new HashMap<>();//記錄當前Node屬於第幾層
        levelMap.put(head, 1);
        int curLevel = 1; //記錄當前在哪一層
        int curWidth = 0; //記錄當前層的寬度(有幾個節點),因為head進去之后沒彈出,所以初始值為0
        int maxWidth = -1;   //記錄最大層的寬度,初始值 -1
        while (!queue.isEmpty()) {
            Node cur = queue.poll(); //彈出一個Node
            int curNodeLevel = levelMap.get(cur); //記錄彈出的Node屬於哪一層(從HahsMap中獲取)
            //如果當前節點所遍歷的層和來到的想統計的層一樣,
            if (curNodeLevel == curLevel) {
                curWidth++;
            } else {//說明到下一層了
                maxWidth = Math.max(maxWidth, curWidth); //統計當前Node之上所有層中最大層的節點數(做比較)
                curLevel++; //跳到下一層
                curWidth = 1;//為什么是1? 比如當前節點2屬於第2層(跳出第1層,不走if),走的是else
                // 但要統計第2層的節點數,所以初始值為1,下次再有第2層的節點被pop時,走正常的if流程
            }
            //能夠進行以上操作前提是:知道每一個Node節點所在的層數   解決辦法:在進棧的時候記錄它的層
            if (cur.left != null) {
                levelMap.put(cur.left, curNodeLevel + 1);//當前Node左節點的所在層數為當前Node所在層數加1
                queue.add(cur.left);
            }
            if (cur.right != null) {
                levelMap.put(cur.right, curNodeLevel + 1);//當前Node右節點的所在層數為當前Node所在層數加1
                queue.add(cur.right);
            }
        }
        maxWidth = Math.max(maxWidth, curWidth);
        return maxWidth;
    }
獲取二叉樹最大層的寬度

實例代碼

package Algorithms;

/**
 * @author : zhang
 * @version : 1.0
 * @date : Create in 2021/8/12
 * @description :
 */

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

public class TreeMaxWidth {

    public static void main(String[] args) {
        Node head = new Node(1);
        head.left = new Node(2);
        head.right = new Node(3);
        head.left.left = null;
        head.left.right = new Node(4);
        head.right.left = new Node(5);
        head.right.right = null;
        head.left.right.left = new Node(6);
        head.left.right.right = new Node(7);
        head.right.left.left = new Node(8);
        head.right.left.right = new Node(9);

        //測試寬度遍歷
        width(head); // 1 2 3 4 5 6 7 8 9

        //測試二叉樹最大層的寬度
        int maxWidth = getMaxWidth(head);
        System.out.println("二叉樹最大層的寬度為:" + maxWidth); // 二叉樹最大層的寬度為:4

    }

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

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

    //寬度遍歷
    public static void width(Node head) {
        if (head == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<>(); //java中,LinkedList就是隊列
        queue.add(head);
        while (!queue.isEmpty()) {
            Node cur = queue.poll();
            System.out.print(cur.value + " ");
            if (cur.left != null) {
                queue.add(cur.left);
            }
            if (cur.right != null) {
                queue.add(cur.right);
            }
        }
        System.out.println();
    }

    //獲取二叉樹中最大層的寬度
    public static int getMaxWidth(Node head) {
        if (head == null) {
            return 0;
        }
        Queue<Node> queue = new LinkedList<>(); //java中,LinkedList就是隊列
        queue.add(head);
        HashMap<Node, Integer> levelMap = new HashMap<>();//記錄當前Node屬於第幾層
        levelMap.put(head, 1);
        int curLevel = 1; //記錄當前在哪一層
        int curWidth = 0; //記錄當前層的寬度(有幾個節點),因為head進去之后沒彈出,所以初始值為0
        int maxWidth = -1;   //記錄最大層的寬度,初始值 -1
        while (!queue.isEmpty()) {
            Node cur = queue.poll(); //彈出一個Node
            int curNodeLevel = levelMap.get(cur); //記錄彈出的Node屬於哪一層(從HahsMap中獲取)
            //如果當前節點所遍歷的層和來到的想統計的層一樣,
            if (curNodeLevel == curLevel) {
                curWidth++;
            } else {//說明到下一層了
                maxWidth = Math.max(maxWidth, curWidth); //統計當前Node之上所有層中最大層的節點數(做比較)
                curLevel++; //跳到下一層
                curWidth = 1;//為什么是1? 比如當前節點2屬於第2層(跳出第1層,不走if),走的是else
                // 但要統計第2層的節點數,所以初始值為1,下次再有第2層的節點被pop時,走正常的if流程
            }
            //能夠進行以上操作前提是:知道每一個Node節點所在的層數   解決辦法:在進棧的時候記錄它的層
            if (cur.left != null) {
                levelMap.put(cur.left, curNodeLevel + 1);//當前Node左節點的所在層數為當前Node所在層數加1
                queue.add(cur.left);
            }
            if (cur.right != null) {
                levelMap.put(cur.right, curNodeLevel + 1);//當前Node右節點的所在層數為當前Node所在層數加1
                queue.add(cur.right);
            }
        }
        maxWidth = Math.max(maxWidth, curWidth);
        return maxWidth;
    }

    //代碼2
    public static int getMaxWidth2(Node head) {
        if (head == null) {
            return 0;
        }
        int maxWidth = 0;
        int curWidth = 0;
        int curLevel = 0;
        HashMap<Node, Integer> levelMap = new HashMap<>();
        levelMap.put(head, 1);
        LinkedList<Node> queue = new LinkedList<>();
        queue.add(head);
        Node node = null;
        Node left = null;
        Node right = null;
        while (!queue.isEmpty()) {
            node = queue.poll();
            left = node.left;
            right = node.right;
            if (left != null) {
                levelMap.put(left, levelMap.get(node) + 1);
                queue.add(left);
            }
            if (right != null) {
                levelMap.put(right, levelMap.get(node) + 1);
                queue.add(right);
            }
            if (levelMap.get(node) > curLevel) {
                curWidth = 0;
                curLevel = levelMap.get(node);
            } else {
                curWidth++;
            }
            maxWidth = Math.max(maxWidth, curWidth);
        }
        return maxWidth;
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM