数据结构--树

树的几个概念

高度:节点到叶子节点的最长路径(边数)
深度:根节点到这个节点所经历的边的数量
层数:深度 + 1
图片说明

二叉树

每个节点最多只有左右2个节点

满二叉树

除了叶子节点外,每个节点都有左右两个节点

完全二叉树

叶子节点都在最底下两层,最后一层的叶子节点都靠左排列

二叉树的遍历

前序遍历 遍历根节点 -> 左节点 -> 右节点

    public void pre(TreeNode root){
        if (root == null) return;
        System.out.println(root.data);
        pre(root.left);
        pre(root.right)
    }

中序遍历 遍历左节点 -> 根节点 -> 右节点

    public void middle(TreeNode root){
        if (root == null) return;
        middle(root.left);
        System.out.println(root.data);
        middle(root.right)
    }

后序遍历 遍历左节点 -> 右节点 -> 根节点

    public void after(TreeNode root){
        if (root == null) return;
        after(root.left);
        after(root.right)
        System.out.println(root.data);
    }
二叉查找树(二叉搜索树)

左节点都小于根节点,右节点都大于根节点

package com.xx;

public class Tree {
    Node root;
    public void pre(Node tree){
        if (tree == null) return;
        System.out.println(tree.data);
        pre(tree.left);
        pre(tree.right);
    }

    public void middle(Node tree){
        if (tree == null) return;
        middle(tree.left);
        System.out.println(tree.data);
        middle(tree.right);
    }

    public void after(Node tree){
        if (tree == null) return;
        after(tree.left);
        after(tree.right);
        System.out.println(tree.data);
    }

    public Node find(int value){
        Node curr = root;
        while(curr != null){
            if (value < curr.data){
                curr = curr.left;
            }else if (value > curr.data) {
                curr = curr.right;
            }else {
                return curr;
            }
        }
        return null;
    }

    public void insert(int data){
        if (root == null){
            root = new Node(data);
            return;
        }

        Node curr = root;
        while (curr != null){
            if (data < curr.data){
                if (curr.left == null){
                    curr.left = new Node(data);
                    return;
                }
                curr = curr.left;
            }else{
                if (curr.right == null){
                    curr.right = new Node(data);
                    return;
                }
                curr = curr.right;
            }
        }
    }

    public void delete(int data){
        Node curr = root;
        Node pp = null;
        while (curr != null && curr.data != data){
            pp = curr;
            if (data > curr.data) {
                curr = curr.right;
            }else{
                curr = curr.left;
            }
        }
        if (curr == null){
            return;
        }

        if(curr.left != null && curr.right != null){
            Node minP = curr.right;
            Node minPP = curr;
            while (minP.left != null){
                minPP = minP;
                minP = minPP.left;
            }
            curr.data = minP.data;
            curr = minP;
            pp = minPP;
        }

        // 删除节点是叶子节点或者仅有一个子节点
        Node child; // p 的子节点
        if (curr.left != null){
            child = curr.left;
        }
        else if (curr.right != null) {
            child = curr.right;
        }
        else {
            child = null;
        }

        // 删除的是根节点
        if (pp == null) {
            root = child;
        }
        else if (pp.left == curr) {
            pp.left = child;
        }
        else {
            pp.right = child;
        }
    }


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

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

平衡二叉树

任意一个节点的左右字数的高度差不超过1

红黑树是一种平衡二叉树

  1. 根节点为黑色
  2. 每个叶子节点都是黑色的空节点(NIL),说明叶子节点不存储数据
  3. 任何相邻的节点都不能同时为红色,说明红色节点都被黑色节点隔开
  4. 每个节点,从该节点到其可达的叶子节点的所有路径,都包含相同数目的黑色节点;

红黑树左旋,右旋 左旋将当前节点拉为儿子节点 右旋将当前节点拉为父亲节点

红黑树插入的节点必须为红色节点,而且新插入的都是放在叶子节点;
红黑树调整主要是旋转以及改变颜色

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务