• 非递归实现二叉查找树


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

    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
    ------------------------------- 问道,修仙 -------------------------------
  • 相关阅读:
    C#/Net代码精简优化技巧(二)【转】
    IsSpecialName特性及其他问题【转】
    &、|与&&、||的比较
    序列化后存储Cookie
    序列化反序列化操作
    C#/Net代码精简优化技巧(一)【转】
    .Net 中的序列化与反序列化【转】
    c#对象序列化(二进制序列化)BinaryFormatter【转】
    POJ 2828 Buy Tickets(单点更新) 详细题解和思路
    Color the ball HDU 1556 (非线段树做法)
  • 原文地址:https://www.cnblogs.com/elvalad/p/4141578.html
Copyright © 2020-2023  润新知