<数据结构与算法>之二叉查找树

来源:互联网 发布:通达信的软件 编辑:程序博客网 时间:2024/05/17 07:16
  1. 基本概念:
    关于二叉查找树的概念我就不在这里说了,可以查看之前的一篇博客二叉树初看。这里主要写对二叉查找树的java 实现吧。
  2. java实现
    1) 二叉查找树数据结构:
private class TreeNode {          private int key;          private TreeNode leftChild;        private TreeNode rightChild;        private TreeNode parent;        public TreeNode(int key, TreeNode leftChild, TreeNode rightChild,                  TreeNode parent) {              this.key = key;              this.leftChild = leftChild;              this.rightChild = rightChild;              this.parent = parent;          }        public int getKey() {              return key;          }        public String toString() {              String leftkey = (leftChild == null ? "" : String                      .valueOf(leftChild.key));              String rightkey = (rightChild == null ? "" : String                      .valueOf(rightChild.key));              return "(" + leftkey + " , " + key + " , " + rightkey + ")";          }    } 

2)查找节点

    /**     * 查找给定的关键字     * */    public TreeNode search(int key) {        TreeNode pNode = root;        while(pNode != null && pNode.key != key) {            if(pNode.key > key) {                pNode = pNode.leftChild;            } else {                pNode = pNode.rightChild;            }        }        return pNode;    }    /**     * 查找最小关键字节点     * @throws Exception      * */    public TreeNode minKeyTreeNode(TreeNode node) throws Exception {        if(node == null) {            throw new Exception("树为空");        }        TreeNode pNode = node;        while(pNode.leftChild != null) {            pNode = pNode.leftChild;        }        return pNode;    }    /**     * 查找最大关键字的节点     * @throws Exception      * */    public TreeNode maxKeyTreeNode(TreeNode node) throws Exception {        if(node == null) {            throw new Exception("树为空");        }        TreeNode pNode = node;        while(pNode.rightChild != null) {            pNode = pNode.rightChild;        }        return pNode;    }    /**     * 获取给定节点的在中序遍历的条件下的后继节点     * 有三个情况:1)如果当前节点有右孩子,则后继是右子树的最左节点     * 2)当前节点无右孩子,如果当前节点是父亲节点的左儿子,则后继是父亲节点     * 3)当前节点无右孩子,且是父亲节点的右孩子,则所在字树遍历完了,向上寻找一个作为左孩子的祖先节点,那下一个遍历的是该祖先节点的父亲节点。     * 如果上面的情况都没有,则该节点是树的最后一个节点,无后继节点。     * */    public TreeNode successorInOrder(TreeNode node) throws Exception {        if(node == null) {            return null;        }        // 如果该节点的右节点不为空,则其后继节点就是右子树中的最小关键字节点        if(node.rightChild != null) {            return minKeyTreeNode(node.rightChild);        }        TreeNode parentNode = node.parent;        while (parentNode != null && node == parentNode.rightChild) {              node = parentNode;              parentNode = parentNode.parent;          }          return parentNode;    }    /**     * 获取给定节点在中序条件下的前序节点     * 如果x有左孩子,则前驱节点是左子树中最大关键字节点     * x无左孩子,若x是父亲节点的右孩子,则x的前驱节点为其父亲节点     * x无左孩子,x是父亲节点的左孩子,则x的前驱节点是x的某一个祖先节点的父亲节点,并且该祖先节点是其父亲节点的右孩子     * */    public TreeNode presuccessor(TreeNode node) {        if(node == null) {            return null;        }        if(node.leftChild != null) {            return maxKeyTreeNode(node.leftChild);        }        TreeNode parentNode = node.parent;        while(parentNode != null && node == parentNode.leftChild) {            node = parentNode;            parentNode = parentNode.parent;        }        return parentNode;    }

3) 插入节点

    /**     * 将给定的关键字插入到二叉查找树中     * */    public void insert(int key) {        TreeNode parentNode = null;        TreeNode newNode =  new TreeNode(key, null, null, null);        TreeNode pNode = root;        if (root == null) {            root = newNode;            return ;        }        while(pNode != null) {            parentNode = pNode;            if(key < pNode.key) {                pNode = pNode.leftChild;            } else if(key > pNode.key) {                pNode = pNode.rightChild;            } else {                return ; // 二叉查找树中已经存在要插入的关键字,返回            }        }        if(key < parentNode.key) {            parentNode.leftChild = newNode;            newNode.parent = parentNode;        } else {            parentNode.rightChild = newNode;            newNode.parent = parentNode;        }    }

4) 删除节点

    /**     * 删除节点     * @throws Exception      * */    public void delete(int key) throws Exception {        TreeNode pNode = search(key);        if(pNode == null) {            throw new Exception("树中不存在要删除的关键字");        }        delete(pNode);    }    /**     * 从二叉查找树中删除给定的节点     * 前置条件:给定节点在二叉查找树中已经存在     * @throws Exception      * */    public void delete(TreeNode pNode) throws Exception {        if(pNode == null) {            return ;        }        if(pNode.leftChild == null && pNode.rightChild == null) {            TreeNode parentNode = pNode.parent;            if(parentNode == parentNode.leftChild) {                parentNode.leftChild = null;            } else {                parentNode.rightChild = null;            }            return ;        }        if(pNode.leftChild == null && pNode.rightChild != null) {            TreeNode parentNode = pNode.parent;            if(pNode == parentNode.leftChild) {                parentNode.leftChild = parentNode.rightChild;                pNode.rightChild.parent = parentNode;            } else {                parentNode.rightChild = pNode.rightChild;                pNode.rightChild.parent = parentNode;            }            return ;        }        if(pNode.leftChild != null && pNode.rightChild == null) {            TreeNode parentNode = pNode.parent;            if(pNode == parentNode.leftChild) {                parentNode.leftChild = pNode.leftChild;                pNode.leftChild.parent = parentNode;            } else {                parentNode.rightChild = pNode.leftChild;                  pNode.rightChild.parent = parentNode;            }            return ;        }        // 该结点左右孩子结点均非空,则删除该结点的后继结点,并用该后继结点取代该结点          TreeNode successorNode = successorInOrder(pNode);//找到该节点的后继节点        delete(successorNode);        pNode.key = successorNode.key;    }

5) 遍历二叉树

原创粉丝点击