二叉搜索树

来源:互联网 发布:世界顶级音乐学院知乎 编辑:程序博客网 时间:2024/06/07 21:48


一、什么是二叉搜索树

         二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于等于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于等于它的根结点的值; 它的左、右子树也分别为二叉排序树


二、查询

定义树的结点类为

class Node{int k;Node left = null;Node right = null;Node p = null;}


查找过程,从树的根节点开始查找,输入树的根节点和需要查找的k值,如果结点存在,返回指向关键字k的结点,否则返回null。



public Node TreeSearch(Node root,int k){if(root==null||k==root.k)return root;if(k<root.k){return TreeSearch(root.left,k);}else{return TreeSearch(root.right,k);}}



三、插入

插入和删除会引起由二叉搜索树的动态集合的变化。一定要修改数据结果来反映这个变化,但修改要保持二叉树搜索树性质成立。

public void TreeInsert(Node root,Node z){Node y = null;Node x = root;while(x!=null){y = x;if(z.k<x.k){x = x.left;}else{x = x.right;}}z.p = y;if(y==null){root = z;}else if(z.k<y.k){y.left = z;}else{y.right = z;}}


四、删除

删除分为三种情况

1、如果z没有孩子结点,那么知识简单地将它删除,并修改它的父结点,用null最为孩子了替换z

2、如果z只有一个孩子,那么将这个孩子提升到树中的z的位置,并修改z的父结点,用z的孩子代替z

3、如果z有两个孩子,那么找z的后继y(一定在z的右子树中)并让其占据树中z的位置,z原来额右子树部分称为y的右子树,并且z的左子树称为y的新的左子树。


为了完成删除操作,我们先来做一下准备工作。

最大关键字元素和最下关键字元素

/** * 获得最小值元素 * @param x * @return */public Node TreeMiniNum(Node x){while(x.left!=null){x = x.left;}return x;}/** * 获得最大值元素 * @param x * @return */public Node TreeMaxiNum(Node x){while(x.right!=null){x = x.right;}return x;}


前驱和后继

一个结点的后继是大于x.key的最小关键词的结点,前驱是小于x.key的最大关键字的结点。


/** * 求后继 * @param x * @return */public Node TreeSuccessor(Node x){if(x.right!=null){return TreeMiniNum(x.right);}Node y = x.p;while(y!=null && x == y.right){x = y;y = y.p;}return y;}




为了在二叉搜索树内移动子树,定义一个子过程TRANSPLANT,它是用另一颗子树替换一棵子树并成为其双亲的孩子结点。当TRANSPLANT用一颗以v为根的子树来替换一颗以u为根的子树时,结点u的双亲就变为结点v的双亲,并最后v成为u的双亲的相应孩子。


public void Transplant(Node root,Node u,Node v){if(u.p==null)root = v;else if(u==u.p.left)u.p.left = v;else u.p.right = v;if(v!=null){v.p = u.p;}}





下面是二叉搜索树删除结点z的删除过程

public void TreeDelete(Node root,Node z){//第一种情况if(z.left==null)Transplant(root, z, z.right);else if(z.right == null)Transplant(root, z, z.left);//第二和第三种情况else {Node y = TreeMiniNum(z.right);if(y.p!=z){//第三种情况Transplant(root, y, y.right);y.right = z.right;y.right.p = y;}//z的后继恰好为z的有右孩子,第二种情况Transplant(root, z, y);y.left = z.left;y.left.p = y;}}





在一颗高度为h的二叉搜素树上,实现动态集合操作Insert和Delete的运行时间均为o(h)。



本文为《算法导论》二叉搜索复习笔记

原创粉丝点击