非递归实现二叉查找树

之前在学习二叉查找树时按照递归方式实现了二叉查找树:

http://www.cnblogs.com/elvalad/p/4129650.html

在实际应用中由于递归的深度和性能等问题会要求使用非递归方式实现二叉查找树的search操作,这里用循环的方式实现put,get,min和max操作。二叉查找树的非递归实现主要依赖二叉树的特点根节点的左子树的key都比根节点的key小,右子树的key都比根节点的key大这一特点,并通过left和right两个指针进行左子树或右子树的遍历,找到相应的key该插入的位置以及搜索相应的key,这里的delete方法直接用之前的递归实现来使用。

二叉查找树查找方法的一个改进可以使用缓存,将最近访问的节点保存在一个Node节点中,这样get或put方法再次访问这个键时使用常数时间就可以了。

/**
 * Created by elvalad on 2014/12/3.
 * 非递归方法实现二叉查找树的各个API
 */
public class BST1<Key extends Comparable<Key>, Value> {
    private Node root;
    private class Node {
        Key key;    /* 该节点的键 */
        Value val;  /* 该节点的值 */
        Node left;  /* 该节点的左子树 */
        Node right; /* 该节点的右子树 */
        Node(Key key, Value val) {
            this.key = key;
            this.val = val;
        }
    }

    /* 非递归方法实现二叉查找树插入元素 */
    public void put(Key key, Value val) {
        Node x = root;
        if (x == null) {
            root = new Node(key, val);
            return;
        }
        //System.out.println("root:" + x.key + " " + x.val);
        while (x != null) {
            int cmp = key.compareTo(x.key);
            if (cmp == 0) {
                x.val = val;
                return;
            } else if (cmp < 0) {
                if (x.left == null) {
                    x.left = new Node(key, val);
                    return;
                }
                x = x.left;
            } else {
                if (x.right == null) {
                    x.right = new Node(key, val);
                    return;
                }
                x = x.right;
            }
        }
    }

    /* 非递归方法实现二叉查找树查找元素 */
    public Value get(Key key) {
        Node x = root;
        if (x == null)
            return null;

        while (x != null) {
            int cmp = key.compareTo(x.key);
            if (cmp == 0) {
                return x.val;
            } else if (cmp < 0) {
                x = x.left;
            } else {
                x = x.right;
            }
        }
        return null;
    }

    /* 非递归方法实现二叉查找树获取最小键节点 */
    public Key min() {
        Node x = root;
        if (x == null) {
            return null;
        }

        while (x != null) {
            if (x.left == null) {
                return x.key;
            } else {
                x = x.left;
            }
        }
        return null;
    }

    private Node min(Node x) {
        /* 如果x为null则根节点即为最小键,否则左子树的最小键即为
         * 整棵树的最小键*/
        if (x.left == null)
            return x;
        return min(x.left);
    }

    /* 非递归方法实现二叉查找树获取最大键节点 */
    public Key max() {
        Node x = root;
        if (x == null) {
            return null;
        }

        while(x != null) {
            if (x.right == null) {
                return x.key;
            } else {
                x = x.right;
            }
        }
        return null;
    }

    private Node max(Node x) {
        if (x.right == null)
            return x;
        return max(x.right);
    }

    private Node deleteMin(Node x) {
        if (x == null)
            return null;

        if (x.left == null) {
            return x.right;
        }
        /* 当x.left不为null时,递归删除x左子树 */
        x.left = deleteMin(x.left);
        return x;
    }

    /* 删除二叉树查找树中键为key的节点 */
    public void delete(Key key) {
        root = delete(root, key);
    }

    private Node delete(Node x, Key key) {
        if (x == null) {
            return null;
        }

        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            x.left = delete(x.left, key);
        } else if (cmp > 0) {
            x.right = delete(x.right, key);
        } else {
            if (x.left == null) {
                return x.right;
            }
            if (x.right == null) {
                return x.left;
            }
            Node t = x;
            x = min(t.right);
            x.left = t.left;
            x.right = deleteMin(x.right);
        }
        return x;
    }

    public static void main(String[] args) {
        BST1<String, Integer> bst1 = new BST1<String, Integer>();

        bst1.put("DDDD", 4);
        bst1.put("CCC", 3);
        bst1.put("A", 1);
        bst1.put("BB", 2);
        bst1.put("FFFFFF", 6);
        bst1.put("EEEEE", 5);
        System.out.println(bst1.get("A"));
        System.out.println(bst1.get("BB"));
        System.out.println(bst1.get("CCC"));
        System.out.println(bst1.get("DDDD"));
        System.out.println(bst1.get("EEEEE"));
        System.out.println(bst1.get("FFFFFF"));

        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
        bst1.delete("A");
        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
        bst1.delete("BB");
        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
        bst1.delete("CCC");
        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
        bst1.delete("DDDD");
        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
        bst1.delete("EEEEE");
        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
        bst1.delete("FFFFFF");
        System.out.println("min:" + bst1.min() + " max:" + bst1.max());
    }

}

 输出结果:

1
2
3
4
5
6
min:A max:FFFFFF
min:BB max:FFFFFF
min:CCC max:FFFFFF
min:DDDD max:FFFFFF
min:EEEEE max:FFFFFF
min:FFFFFF max:FFFFFF
min:null max:null

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/elvalad/p/4141578.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞