数据结构

数据结构

简单二叉树

树包括 左子右子树:节点 key value值

添加元素

给指定节点x添加元素

若头节点为空,则最先给头节点赋值,若头节点不为空 ,则进行key与x.key比较 若大于 则向右递归添加 若x.left 或者x.right =null 则让 x.left 或者x.right = put(x.right,key,value)

查找

在指定节点中查找 若key>x.key则向右插 若小于向左查,若等于 则返回value 若没有 返回null

删除

在指定节点中进行查找,若key>x.key则向右查,若key<x.key向左查,

若等于 则删除该节点

  • 若左子树不存在,则让他的右子树,
  • 若右子树不存在,则返回他的左子树
  • 若左右子树都存在的情况下,n-- ;建一个minNode,minNode:右子树的最左节点,删除最左节点,将x的左右子节点赋给minNode的左右子节点,让 将minNode的值赋给x;
package com.AGui.tree;

public class BinaryTree<Key extends Comparable<Key>, Value> {
    //根节点
    private Node root;

    //记录元素个数
    private int N;

    private class Node {
        public Key key;
        public Value value;
        //记录左子节点
        public Node left;
        // 记录右子节点
        public Node right;

        public Node(Key key, Value value, Node left, Node right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }

    }

    // 获取树中元素个数
    public int size() {
        return N;
    }

    //向树中添加元素值
    public void put(Key key, Value value) {
        root = put(root, key, value);
    }

    //向指定树x中插入key value  返回添加元素后的树
    public Node put(Node x, Key key, Value value) {
        //如果x为空
        if (x == null) {
            N++;
            return new Node(key, value, null, null);
        }
        // 如果x不为空 比较key 若key大于x.key
        int i = key.compareTo(x.key);
        if (i > 0) {
            // 若大于则向右继续找
            x.right = put(x.right, key, value);
        }
        // 若小于则向左继续找
        else if (i < 0) {
            x.left = put(x.left, key, value);

        }
        // 若等于替换value值
        else {
            x.value = value;
        }

        return x;
    }

    //查找树中key对应的value的值
    public Value get(Key key) {
        return get(root, key);
    }

    //查找指定树中的值
    public Value get(Node x, Key key) {
        //若该树为null 则返回null
        if (x == null) {
            return null;
        }
        int i = key.compareTo(x.key);

        //若该树不为null,若key大于x.key向右找 若小于 想左找 若等于 取出
        if (i > 0) {
            return get(x.right, key);
        } else if (i < 0) {
            return get(x.left, key);
        } else
            return x.value;
    }

    //删除树中的key
    public void delete(Key key) {
        root = delete(root, key);
    }

    //删除指定树中的key
    public Node delete(Node x, Key key) {
        //如果x为null 返回null
        if (x == null)
            return null;


        //x不为null key和x.key进行大小比较

        int i = key.compareTo(x.key);
        //大于 向右子树进行递归
        if (i > 0) {
            x.right = delete(x.right, key);
        }
        // 小于 向左子树进行递归
        if (i < 0) {
            x.left = delete(x.left, key);
        }
        // 等于
        else {
            //个数减一
            N--;
            //新节点的key等于当前节点的key 意思就是删除当前节点
            //1.1如果当前节点的左子树不存在
            if (x.left == null) {
                return x.right;
                // 1.2如果当前结点的右子树不存在
            }
            if (x.right == null) {
                return x.left;
            }
            // 若左右子树都存在
            // 找到替换的节点进行替换 替换节点:右子树的最左边的节点
            else {
                Node minNode = x.right;
                while (minNode.left != null) {
                    minNode = minNode.left;
                }
                //删除右子树最小节点
                Node n = x.right;
                if (n.left != null) {
                    if (n.left.left == null) {
                        n.left = null;
                    } else {
                        n = n.left;
                    }
                }
                //将minNode替换到被删除的节点位置
                minNode.left = x.left;
                minNode.right = x.right;
                x = minNode;

            }
        }
        return x;
    }

    //查找最小键
    public Key min() {
        return min(root).key;
    }

    public Node min(Node x) {
        if (x.left != null) {
            return min(x.left);
        } else {
            return x;
        }
    }

    //查找最大键
    public Key max() {
        return max(root).key;
    }

    public Node max(Node x) {
        if (x.right != null) {
            return max(x.right);
        } else return x;
    }
}

二叉树的先序遍历

//获取整个树的所有的键
public List<Key> preErgodic(){
    LinkedList<Key> keys = new LinkedList<>();
    preErgodic(root,keys);
    return keys;

}
//获取指定树中所有的键
private void preErgodic(Node x, Queue<Key> keys){
    if (x==null){
        return;
    }
    keys.add(x.key);
    if(x.left!=null){
        preErgodic(x.left,keys);
    }if(x.right!=null){
        preErgodic(x.right,keys);
    }
}

中序遍历

//获取所有树的中序遍历
public List<Key> midErgodic(){
    LinkedList<Key> keys = new LinkedList<>();
    midErgodic(root,keys);
    return keys;

}
//获取指定树的中序遍历
private void midErgodic(Node x,List<Key> keys){
    if(x==null){
        return;
    }
    if(x.left!=null){
        midErgodic(x.left,keys);
    }
    keys.add(x.key);
    if(x.right!=null){
        midErgodic(x.right,keys);
    }
}

层序遍历

层序遍历:广度优先

首先将头节点放入节点队列,然后判断 ,若节点队列的长度为0 则说明所有已经便利完了

循环中:队列弹出一个节点,将其key加入到keys队列中,对该节点进行判断,若有左子节点,将左子节点加入到节点队列中,若有右子节点,将其加入到队列中,若没有 则进行下次循环

//层序遍历
public List<Key> layerErgodic(){
    LinkedList<Node> node = new LinkedList<>();
    LinkedList<Key> keys= new LinkedList<>();
    //最先弹入根节点,判断有没有左子节点 若有 放入队列中,若没有判断有没有右子节点,若有 放在队列中
    node.addFirst(root);
    while (!node.isEmpty()){
        //节点队列中弹出的节点 放入到keys中
        Node n = node.remove();
        keys.add(n.key);
        if(n.left!=null){
            node.add(n.left);
        }
        if(n.right!=null){
            node.add(n.right);
        }
    }
    return keys;
}

最大深度

//获取树的最大深度
public int maxDepth(){
    return maxDepth(root);
}
//获取节点的最大深度
private int maxDepth(Node x){
    int max = 0;
    int maxLeft = 0;
    int maxRight = 0;
    if(x==null){
        return 0;
    }
    if(x.left!=null){
       maxLeft= maxDepth(x.left);
    }
    if(x.right!=null){
        maxRight = maxDepth(x.right);
    }
     max= maxLeft>maxRight?maxLeft+1:maxRight+1;
    return max;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值