算法4-9:BST顺序操作
2014-06-10 19:49
134 查看
最大值最小值
最小值就是最左侧的节点,最大值就是最右侧的节点。代码
public Key min() {
if(root == null) return null;
Node node = root;
while(node.left != null) {
node = node.left;
}
return node.key;
}
public Key max() {
if(root == null) return null;
Node node = root;
while(node.right != null) {
node = node.right;
}
return node.key;
}
floor操作
floor操作就是要在集合中找出不大于指定值的最大值。比如集合为{1,3,5,9},floor(8)是5,因为只有5不超过8,而且于8最接近。计算floor(x)的时候有三种情况:
要找的节点的值刚好等于x,那么floor(x)就为x
如过x比节点的值小,那么floor(x)的节点一定在左边
如果x比节点的值大,那么floor(x)有可能在右边,也有可能该节点就是floor(x)。只要能在右子树中找到小于等于x的值即可。
因此代码如下:
public Key floor(Key key) { return floor(root, key); } private Key floor(Node node, Key key) { if(node == null) return null; int compare = key.compareTo(node.key); // 如果节点的值和key相等,则该节点就是floor值 if(compare == 0) return node.key; // 如果key比该节点小,那么floor值一定在节点的左边。 if(compare < 0) return floor(node.left, key); // 如果key比该节点大,那么floor值一定在节点的右边。 Key k = floor(node.right, key); if(k != null) return k; return node.key; }
size操作
size操作就是用于统计某个树的节点数量,便于实现select操作和rank操作。要实现size操作,就需要在节点中增加count成员变量,用于统计节点数量。
class Node { Key key; Value value; Node left; Node right; int count; }
size函数的代码如下:
private int size(Node node) { if(node == null) return 0; else return node.count; }
需要修改put操作,记录parent.count。
private Node put(Node parent, Key key, Value value) { // 如果parent是空的,创建一个新的节点 if(parent == null) { Node node = new Node(); node.key = key; node.value = value; node.count = 1; return node; } // 递归插入 int compare = key.compareTo(parent.key); if(compare < 0) { parent.left = put(parent.left, key, value); // 注意:返回值需要赋值给parent.left } else if(compare > 0) { parent.right = put(parent.right, key,value); } else { parent.value = value; } parent.count = 1 + size(parent.left) + size(parent.right); return parent; }
rank操作
rank操作就是要找出某个键在集合中的排名。采用递归的方法就非常方便实现。
public int rank(Key key) { return rank(root, key); } private int rank(Node node, Key key) { if(node == null) { return 0; } int compare = key.compareTo(node.key); if(compare < 0) { return rank(node.left, key); } else if(compare > 0) { return size(node.left) + 1 + rank(node.right, key); } else { return size(node.left); } }
keys操作
keys操作就是按顺序取出所有的键。对于每个节点,获取左侧节点的所有键,自己的键,获取右侧节点的所有键。也就是中序遍历。
public Iterable<Key> inorder() { Queue<Key> q = new LinkedList<Key>(); inorder(root, q); return q; } private void inorder(Node node, Queue<Key> q) { if(node == null) return; inorder(node.left, q); q.add(node.key); inorder(node.right, q); }
复杂度
对于二叉查找树,所有操作的复杂度都是一样的,复杂度和树的高度成正比。相关文章推荐
- 顺序表的定义、初始化、及插入、删除、查询操作,将算法转化成具体的代码
- 编程菜鸟的日记-初学尝试编程-顺序表的类定义及其基本操作算法(创建表、元素插入、元素删除、顺序查找、测表空、求表长、输出等)
- 顺序表操作算法实现
- 算法数据结构 单链表的实现+操作 以及和顺序表的对比
- 第八周实践项目3 顺序串一些算法操作
- 数据结构与算法———顺序表的基本操作
- 妙趣横生的算法(1)之顺序表操作
- 编写程序,实现顺序栈的创建、进栈和出栈等基本操作算法。
- 顺序线性表的基本操作算法
- 编写算法,对非递减顺序存储的线性表操作,将表中相等的多余元素删除,变为严格递增
- 顺序队列的算法操作
- 顺序表的算法操作
- 数据结构与算法:顺序串基本操作
- 域环境中操作主机的关机顺序
- 算法(05):基本链表的操作及双向链表
- 顺序表的操作
- 解析思科IOS操作顺序
- 理解tcp顺序释放操作和tcp的半关闭
- 巧用标准c++中的算法函数,对数组进行操作
- 顺序队列结构及操作