【算法导论学习-24】二叉树专题2:二叉搜索树(Binary Search Tree,BST)
2014-08-28 14:18
696 查看
一、 二叉搜索树(Binary SearchTree,BST)
对应《算法导论》第12章。相比一般二叉树,BST满足唯一的条件:任意节点的key>左孩子的key,同时<右孩子的key。1. 节点类:
public class BinarySearchTreesNode<T> { private int key; private T satelliteData; private BinarySearchTreesNode<T> parent, leftChild, rightChild; public BinarySearchTreesNode(int key, T satelliteData) { // TODO 自动生成的构造函数存根 this.key = key; this.satelliteData = satelliteData; parent = leftChild = rightChild = null; } public T getSatelliteData() { return satelliteData; } public void setSatelliteData(T satelliteData) { this.satelliteData = satelliteData; } public BinarySearchTreesNode<T> getParent() { return parent; } public void setParent(BinarySearchTreesNode<T> parent) { this.parent = parent; } public BinarySearchTreesNode<T> getLeftChild() { return leftChild; } public void setLeftChild(BinarySearchTreesNode<T> leftChild) { this.leftChild = leftChild; } public BinarySearchTreesNode<T> getRightChild() { return rightChild; } public void setRightChild(BinarySearchTreesNode<T> rightChild) { this.rightChild = rightChild; } public int getKey() { return key; } }
2. BST的建立
/** * @author Administrator * */ public class BinarySearchTree<T> { private BinarySearchTreesNode<T> root; public BinarySearchTree() { // TODO 自动生成的构造函数存根 root = null; } public BinarySearchTreesNode<T> getRoot() { return root; } public void setRoot(BinarySearchTreesNode<T> root) { this.root = root; } public BinarySearchTree(BinarySearchTreesNode<T> binarySearchTreesNode) { // TODO 自动生成的构造函数存根 root = binarySearchTreesNode; } }
二、 BST遍历
可以使用一般二叉树的遍历方法。1. 中序遍历
/* 算法导论288页伪代码,中序遍历, */ public void inOrderTreeWalk(BinarySearchTreesNode<T> binarySearchTreesNode) { if (binarySearchTreesNode != null) { inOrderTreeWalk(binarySearchTreesNode.getLeftChild()); System.out.println(binarySearchTreesNode.getKey() + ":" + binarySearchTreesNode.getSatelliteData()); inOrderTreeWalk(binarySearchTreesNode.getRightChild()); } } public void inOrderTreeWalk() { inOrderTreeWalk(root); }
三、 BST的其他操作
1. 查找
《算法导论》P290 递归版本和循环版本2. 最大key节点和最小key节点
《算法导论》P291public static BinarySearchTreesNode<String> getMinimum(BinarySearchTree<String> binarySearchTree) { BinarySearchTreesNode<String> node=binarySearchTree.getRoot(); while (node.getLeftChild()!=null) { node=node.getLeftChild(); } return node; }
3. 后继和前驱
后继:节点x的后继指的是大于x.key的最小key的节点。两种情况:1) x的右子树不为空:后继为x的右子树最小key节点。
2) x的右子树为空,x为左节点:返回x的父节点;
3) x的右子树为空,x为右节点:x的父类节点都是有节点,则最终返回null;只要x的父类节点有左节点点,则返回该父类节点的父节点即可。
伪代码:
TREE-SUCCESSOR(X)
if x.right≠NIL
return TREE-MINIMUM(x.right)
y=x.parent
while y≠NIL and x==y.right
x=y
y=y.parent
return y
*******************************************************************************
《算法导论》P293页课后题12.2-3要求写出前驱的伪代码。同理,前驱即节点x的前驱指的是小于x.key的最大key的节点。仿照上面伪代码:
TREE-PREDECESSOR(X)
if x.left≠NIL
return TREE-MAXIMUM(x.left)
y=x.parent
while y≠NIL and x==y.left
x=y
y=y.parent
return y
4. 插入
插入节点一定是叶子节点,所以不断遍历到最后符合条件的位置即可。/* * 算法导论294页伪代码,BinarySearchTreesNode<T> * x从root开始遍历,只要binarySearchTreesNode.getKey()<x.getKey()则遍历左边,反之遍历右边 * 最后temp是插入位置,x=null */ public void insert(BinarySearchTreesNode<T> binarySearchTreesNode) { BinarySearchTreesNode<T> temp = null; BinarySearchTreesNode<T> x = root; while (x != null) { temp = x; if (binarySearchTreesNode.getKey() < x.getKey()) { x = x.getLeftChild(); } else { x = x.getRightChild(); } } if (temp == null) { root = binarySearchTreesNode; } else if (binarySearchTreesNode.getKey() < temp.getKey()) { temp.setLeftChild(binarySearchTreesNode); } else { temp.setRightChild(binarySearchTreesNode); } // System.out.println("插入完成!"); }
5. 删除
较复杂,《算法导论》P296****************************************************************************
四、 BST转化为双向链表
参考1:/article/1491839.html参考2:http://zhedahht.blog.163.com/blog/static/254111742007127104759245/
思路:通过递归的方式获取最左边的节点即最小的节点为头结点head,生成一个初始值为null的尾节点tail,然后递归的方式进行中序遍历,将节点tail进行移动。
java实现:
/** * @author曹艳丰 * */ public classBinarySearchTreeTest { /** * @param args */ public static void main(String[] args) { // TODO自动生成的方法存根 BinarySearchTreesNode<String>node1=newBinarySearchTreesNode<String>(6, new String("曹艳丰")); BinarySearchTreesNode<String>node2=newBinarySearchTreesNode<String>(5, new String("习近平")); BinarySearchTreesNode<String>node4=newBinarySearchTreesNode<String>(8, new String("王岐山")); BinarySearchTreesNode<String>node3=newBinarySearchTreesNode<String>(7, new String("李克强")); BinarySearchTreesNode<String>node0=newBinarySearchTreesNode<String>(4, new String("温家宝")); node1.setLeftChild(node2); node1.setRightChild(node4); node2.setLeftChild(node0); node4.setLeftChild(node3); BinarySearchTreesNode<String>head=toLinkedList(node1); while (head!=null) { System.out.println(head.getKey()); head=head.getRightChild(); } } public staticBinarySearchTreesNode<String>toLinkedList(BinarySearchTreesNode<String> root) { if (root==null) { return null; } BinarySearchTreesNode<String>head=getLeftMostNode(root); BinarySearchTreesNode<String>tail=null; convert(root, tail); return head; } /*将二叉树通过递归的方式转化为双向链表*/ public staticBinarySearchTreesNode<String> convert(BinarySearchTreesNode<String>root,BinarySearchTreesNode<String>tail){ if (root==null) { return null; } BinarySearchTreesNode<String>leftNode=root.getLeftChild(); if (leftNode!=null) { tail=convert(leftNode, tail); } /*tail是链表末尾,加入下一个节点后tail后移*/ if (tail!=null) { tail.setRightChild(root); } tail=root; BinarySearchTreesNode<String>rightNode=root.getRightChild(); if (rightNode!=null) { tail=convert(rightNode, tail); } return tail; } public staticBinarySearchTreesNode<String>getLeftMostNode(BinarySearchTreesNode<String> root) { BinarySearchTreesNode<String>temp=root; while (temp.getLeftChild()!=null) { temp=temp.getLeftChild(); } return temp; } }
****************************************************************************
【一道面试题】:BST如何高效地找到中位数。
参考:/article/8206122.html
答案:BST转化为双向链表,双向链表是排好序的,两个指针一个速度是另一个两倍,快的移到最后,慢的即中位数。
相关文章推荐
- 【算法导论学习-26】 二叉树专题4:红黑树、AVL树、B-Tree
- 二叉查找树(binary search tree (BST))--算法导论示例
- 二叉查找树(binary search tree (BST))--算法导论示例
- 【算法导论学习-25】 二叉树专题3:Treaps
- 【LeetCode-面试算法经典-Java实现】【098-Validate Binary Search Tree(验证二叉搜索树)】
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- Binary Search Tree(BST)二叉搜索树的实现-java语言
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- leetcode 235. Lowest Common Ancestor of a Binary Search Tree 二叉搜索树BST的最近公共祖先LCA + 深度优先遍历DFS
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- 【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】
- 【算法总结】Binary Tree & Binary Search Tree 二叉树
- LeetCode(Validate Binary Search Tree) 判断一个二叉树是否是二叉搜索树
- Leetcode Convert Sorted Array to Binary Search Tree 有序数组转换成二叉搜索树BST
- 【算法导论学习-30】 二叉树专题5:二叉树类型的判断
- 二叉排序树(Binary Sort Tree,二叉查找树,二叉搜索树)--【算法导论】
- 二叉搜索树;二叉查找树;二叉排序树;binary search tree(BST)
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- 树---Binary Search Tree(二叉搜索树BST)
- 判断给定二叉树是否是二叉搜索树(LeetCode: Validate Binary Search Tree)