数据结构之二叉树(二)(附Java、C++代码)

        本文仍然记录二叉树的相关例题,建议先看看上一篇文章中的二叉树基本知识,然后再继续今天的题目~

在每个树行中找最大值

        和上一篇的求二叉树的平均值很相似,这里是求最大值,所以解题如下:

        C++ 版本:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int> result;
        queue<TreeNode*> que;
        if(root != NULL) que.push(root);
        while(!que.empty()){
            int size = que.size();
            int maxValue = INT_MIN; // 取每一层的最大值
            while(size--){
                TreeNode* node = que.front();
                que.pop();
                maxValue = node->val > maxValue ? node->val : maxValue;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(maxValue); // 把最大值放进数组
        }
        return result;
    }
};

        Java 版本:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        Deque<TreeNode> que = new LinkedList<>();
        if(root != null) que.add(root);
        List<Integer> result = new ArrayList<>();
        while(!que.isEmpty()){
            int size = que.size();
            int max = Integer.MIN_VALUE;
            for(int i = 0;i < size; i++){
                TreeNode node = que.poll();
                max = Math.max(max,node.val);
                if(node.left != null) que.add(node.left);
                if(node.right != null) que.add(node.right);
            } 
            result.add(max);
        }
        return result;
    }
}

填充每个节点的下一个右侧指针

        给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

        Java 版本:

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, Node _left, Node _right, Node _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
*/

class Solution {
    public Node connect(Node root) {
        Deque<Node> que = new LinkedList<>();
        if(root != null) que.add(root);

        while(!que.isEmpty()){
            int size = que.size();
            Node cur = que.poll();
            //这里是为了防止后续对空指针操作
            if(cur.left != null) que.add(cur.left);
            if(cur.right != null) que.add(cur.right);

            for(int i = 1; i < size; i++){
                Node cnext = que.poll();
                if(cnext.left != null) que.add(cnext.left);
                if(cnext.right != null) que.add(cnext.right);
                cur.next = cnext;
                cur = cnext;
            }
        }
        return root;
    }
}

        C++ 版本:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*> que;
        if(root != NULL) que.push(root);
        while(!que.empty()){
            int size = que.size();
            Node* cur;
            Node* cnext;
            for(int i = 0;i < size; i++){
                if(i == 0){
                    cur = que.front(); // 取出一层的头结点
                    que.pop();
                    cnext = cur;
                } else{
                    cnext = que.front();
                    que.pop();
                    cur->next = cnext;  // 本层前一个节点next指向本节点
                    cur  = cnext;
                }
                if(cnext->left) que.push(cnext->left);
                if(cnext->right) que.push(cnext->right);
            }
            cur->next = NULL;  // 本层最后一个节点指向NULL
        }
        return root;
    }
};

翻转二叉树

        给定二叉树的根节点,翻转这颗二叉树,并返回其根节点

        C++ 版本:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root == NULL) return root;
        swap(root->left,root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};

        Java 版本:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null)  return root;
        swap(root);
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
    private void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

平衡二叉树  

        给定一个二叉树,判断它是否是高度平衡的二叉树。

        C++ 版本:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isBalanced(TreeNode* root) {
        return(getHeight(root)>=0);
    }
    int getHeight(TreeNode* node){
        if(node == NULL) return 0;
        int leftHeight = getHeight(node->left);   //左
        if(leftHeight == -1) return -1;   
        int rightHeight = getHeight(node->right);   //右
        if(rightHeight == -1) return -1;
        int result;
        if(abs(rightHeight-leftHeight) > 1) result = -1;
        else{
            result = 1 + max(rightHeight,leftHeight);  //中
        }
        return result;
    }
};

        Java 版本:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        return getHeight(root) == -1 ? false : true;
    }
    private int getHeight(TreeNode node){
        if (node == null) return 0;
        int leftHeight = getHeight(node.left);
        if (leftHeight == -1) return -1;
        int rightHeight = getHeight(node.right);
        if (rightHeight == -1) return -1;
        if (Math.abs(rightHeight - leftHeight) > 1) return -1;
        return Math.abs(rightHeight - leftHeight) > 1 ? -1 : 1 + Math.max(leftHeight, rightHeight);
    }
}

二叉搜索树中的插入操作

        给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

        C++ 版本:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == NULL){
            TreeNode* node = new TreeNode(val);
            return node;
        }
        if(root->val > val) root->left = insertIntoBST(root->left,val);
        if(root->val < val) root->right = insertIntoBST(root->right,val);
        return root;
    }
};

        Java 版本: 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) {
            TreeNode node = new TreeNode(val);
            return node;
        }
        if(root.val > val) root.left = insertIntoBST(root.left,val);
        if(root.val < val) root.right = insertIntoBST(root.right,val);
        return root;
    }
}

删除二叉搜索树中的节点

        C++ 版本:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        //根节点为空
        if(root == nullptr) return nullptr;  
        //找到那个值
        if(root->val == key){
            //左右孩子都为空,即删除的是叶子节点,只需要返回为空
            if(root->left == nullptr && root->right == nullptr){
                delete root;
                return nullptr;
            }
            //右孩子为空,左孩子不为空,让当前节点的左孩子指向父节点
            else if(root->right == nullptr && root->left != nullptr){
                delete root;
                return root->left;
            } 
            //左孩子为空,右孩子不为空,让当前节点的右孩子指向父节点
            else if(root->left == nullptr && root->right != nullptr) {
                delete root;
                return root->right;
            }
            //删除的节点又有左孩子又有右孩子,将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
            //返回删除节点右孩子为新的根节点
            else{
                //向右子树寻找最小节点
                TreeNode* cur = root->right;
                while(cur->left != nullptr){
                    cur = cur->left;
                }
                    cur->left = root->left;
                    TreeNode* temp = root;
                    root = root->right;
                    delete temp;
                    return root;
            }
        }
        if(key < root->val) root->left = deleteNode(root->left,key);
        if(key > root->val) root->right = deleteNode(root->right,key);
        return root;
    }
};

        Java 版本:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null) return null;
        if(root.val == key){
            if(root.left != null && root.right == null) return root.left;
            if(root.right != null && root.left == null) return root.right;
            if(root.left == null && root.right == null) return null;
            else{
                TreeNode cur = root.right;
                while(cur.left != null){
                    cur = cur.left;
                }
                cur.left = root.left;
                return root.right;
            }
        }
        if(root.val > key) root.left = deleteNode(root.left,key);
        if(root.val < key) root.right = deleteNode(root.right,key);
        return root;
    }
}

        二叉树的部分就先到这了吧 ,一起打卡加油啊!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
哈夫曼树是一种特殊的二叉树,它的每个叶子节点都对应一个权值,而非叶子节点则没有权值。哈夫曼树的构建过程是通过不断合并权值最小的两个节点来实现的,直到最终只剩下一个节点为止。哈夫曼树常用于数据压缩算法中。 以下是哈夫曼树的Java代码实现: ```java import java.util.PriorityQueue; public class HuffmanTree { private Node root; private static class Node implements Comparable<Node> { private final char ch; private final int freq; private final Node left, right; Node(char ch, int freq, Node left, Node right) { this.ch = ch; this.freq = freq; this.left = left; this.right = right; } public boolean isLeaf() { return left == null && right == null; } public int compareTo(Node that) { return this.freq - that.freq; } } public HuffmanTree(String s) { int[] freq = new int[256]; for (int i = 0; i < s.length(); i++) { freq[s.charAt(i)]++; } PriorityQueue<Node> pq = new PriorityQueue<>(); for (char c = 0; c < 256; c++) { if (freq[c] > 0) { pq.offer(new Node(c, freq[c], null, null)); } } while (pq.size() > 1) { Node left = pq.poll(); Node right = pq.poll(); Node parent = new Node('\0', left.freq + right.freq, left, right); pq.offer(parent); } root = pq.poll(); } public String encode(String s) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { Node x = root; while (!.isLeaf()) { if (s.charAt(i) == x.left.ch) { sb.append('0'); x = x.left; } else { sb.append('1'); x = x.right; } } sb.append(x.ch); } return sb.toString(); } public String decode(String s) { StringBuilder sb = new StringBuilder(); Node x = root; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '0') { x = x.left; } else { x = x.right; } if (x.isLeaf()) { sb.append(x.ch); x = root; } } return sb.toString(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值