有序符号表(二叉树实现,JAVA,算法(四))
来源:互联网 发布:宿迁12345网络问政电话 编辑:程序博客网 时间:2024/05/29 04:22
二叉树的实现和链表的节点是一致的,一个节点里面包含了键值对。只是由于二叉树的特性,便于插入,删除,查询等操作。二叉树的性质使这些操作都可以在logN的时间完成。但是,,,由于执行插入操作的不确定性,比如大多的升序或者降序插入,将导致二叉树的高度像链表一样,不再具有二叉树特有的logN的高度了。所以基于二叉树之上,一种可以维持自身高度的树出现了,那就是红黑树。下一篇再介绍红黑树。
package com.lizi.datastructure.symboltable;import java.util.ArrayList;import java.util.List;//二叉搜索树,继承的类在上一篇中有写到public class BinarySearchTreeST<Key extends Comparable<Key>,Value> extends SymbolTable<Key,Value> { private Node root;//根节点 private class Node{ private Key key; //键 private Value value; //值 private Node left; //左孩子 private Node right; //右孩子 private int size; //以该节点为根的子树中节点总数 public Node(Key key,Value value,int size){ this.key=key; this.value=value; this.size=size; } } @Override public void put(Key key, Value value) { if(value==null) {delete(key); return;} root=put(root, key, value); } private Node put(Node root,Key key,Value value) { if(root==null) return new Node(key, value, 1); int cmp=key.compareTo(root.key); if(cmp<0) root.left=put(root.left, key, value); else if(cmp>0) root.right=put(root.right, key, value); else root.value=value; root.size=size(root.left)+size(root.right)+1; return root; } @Override public Value get(Key key) { return get(root, key); } private Value get(Node root,Key key) { if(root==null) return null; int cmp=key.compareTo(root.key); if(cmp<0) return get(root.left, key); else if(cmp>0) return get(root.right, key); else return root.value; } @Override public Value delete(Key key) { Value value=get(key); root=delete(root, key); return value; } private Node delete(Node root,Key key) { if(root==null) return null; int cmp=key.compareTo(root.key); if (cmp<0) root.left=delete(root.left, key); else if(cmp>0) root.right=delete(root.right, key); else{//删除操作 if(root.right==null) return root.left;//左右孩子不全,直接替补上去 if(root.left==null) return root.right; Node node=root;//包含左右孩子的删除操作 root=min(node.right); root.right=deleteMin(node.right); root.left=node.left; } root.size=size(root.left)+size(root.right)+1; return root; } @Override public int size() { return size(root); } private int size(Node root) { if (root==null) return 0; else return root.size; } @Override public Key min() { return min(root).key; } private Node min(Node root) { if(root.left==null) return root; else return root.left; } @Override public Key max() { return max(root).key; } private Node max(Node root) { if(root.right==null) return root; else return root.right; } @Override public Key floor(Key key) { Node node=floor(root, key); if(node==null) return null; return node.key; } //找到第一个小于等于key的节点,再在它的右子树的左子树中找寻是否有小于key的节点 //如果有,那么这个键就是最接近key的节点,一个闪电形状 private Node floor(Node root,Key key) { if(root==null) return null; int cmp=key.compareTo(root.key); if(cmp==0) return root; if(cmp<0) return floor(root.left, key); Node node=floor(root.right, key); if (node!=null) return node; else return root; } @Override public Key ceiling(Key key) { Node node=ceiling(root, key); if(node==null) return null; return node.key; } private Node ceiling(Node root,Key key) { if(root==null) return null; int cmp=key.compareTo(root.key); if(cmp==0) return root; if(cmp>0) return floor(root.right, key); Node node=floor(root.left, key); if (node!=null) return node; else return root; } @Override public int rank(Key key) { return rank(root, key); } //返回以root为根节点的子树中小于key的键的数量 private int rank(Node root,Key key) { if(root==null) return 0; int cmp=key.compareTo(root.key); if(cmp<0) return rank(root.left, key); else if(cmp>0) return rank(root.right, key)+size(root.left)+1; else return size(root.left); } @Override public Key select(int index) { if(index>=size()) return null; return select(root,index).key; } //返回下标为index的键 private Node select(Node root,int index) { if(root==null) return null; int size=size(root.left); if(size>index) return select(root.left, index); else if(size<index) return select(root.right, index); else return root; } //将下标位于low-high之间的所有键放入链表中 @Override public Iterable<Key> keys(Key low, Key high) { List<Key> list=new ArrayList<Key>(); keys(root,list,low,high); return list; } private void keys(Node root,List<Key> list,Key low, Key high) { if(root==null) return; int cmplow=low.compareTo(root.key); int cmphigh=high.compareTo(root.key); if(cmplow<0) keys(root.left, list, low, high); if(cmphigh<=0&&cmphigh>=0) list.add(root.key); if(cmphigh>0) keys(root.right, list, low, high); } //删除最小的键 public void deleteMin(){ root=deleteMin(root); } private Node deleteMin(Node root){ if(root.left==null) return root.right; root.left=deleteMin(root.left);//如果最小节点有右孩子,那么替代自身成为其父节点的左孩子 root.size=size(root.left)+size(root.right)+1;//左右孩子加上自身 return root; } //删除最大的键 public void deleteMax(){ deleteMax(root); } private Node deleteMax(Node root){ if(root.right==null) return root.left; root.right=deleteMin(root.right);//如果最小节点有左孩子,那么替代自身成为其父节点的右孩子 root.size=size(root.left)+size(root.right)+1;//左右孩子加上自身 return root; } public void print() { print(root); } private void print(Node root) { if(root==null) return; print(root.left); System.out.println(" 键:"+root.key+" 值:"+root.value); print(root.right); }}
阅读全文
0 0
- 有序符号表(二叉树实现,JAVA,算法(四))
- 有序符号表(数组实现,JAVA,算法(四),二分法)
- 数据结构实现之有序符号表BST二叉查找树
- 无序符号表(链表实现,JAVA,算法(四))
- 笔试面试算法经典--二叉搜索树转有序的双向链表(Java)
- 二叉查找树(二叉排序树、有序二叉树)算法分析及实现
- 有序数组实现符号表
- 《 常见算法与数据结构》符号表ST(2)——初等实现分析和有序符号表
- 有序二叉树的算法
- 算法之 有序链表和平衡二叉树 有序数组与平衡二叉树
- 有序二叉树的实现
- 有序二叉树的实现
- 数据结构实现之有序符号表BinarySearchST(使用有序数组的二分查找)
- 算法基础 - 二叉查找树变成有序双向链表
- java 二叉树实现算法
- 《算法4》符号表以及二叉查找树
- 查找(二):有序符号表
- Java合并两个有序序列算法实现
- IAR开发环境使用串口printf输出(基于STM8L15x系列单片机)
- linux 修改openwrt ntp服务器
- Spring的java配置方式
- Yii2 使用select2 组件实现下拉搜索
- 面向对象六大原则
- 有序符号表(二叉树实现,JAVA,算法(四))
- Struts2 官方教程:通用方法选择
- 项目管理——如何有效的沟通
- 51nod 1307 绳子与重物
- hyperscan示例解读pcapscan
- A
- 统计自然语言处理2----数学基础(一)
- 关于消息队列的使用场景
- 使用Eclipse + OpenCV + C++ 环境搭建(一)