二分搜索树详细操作:

**二分搜索树
树结构简介
树结构本身是一种天然的组织结构,将数据使用树结构存储后,会大幅高效率。
什么是二叉树
和链表一样,动态数据结构
class Node{
E e;
Node left; //左孩子
Node right; //右孩子
}
多叉树(多个子结点)
二叉树具有唯一根节点
二叉树中每个结点最多有两个孩子,没有孩子的结点称之为叶子结点
二叉树中每个结点最多有一个父亲结点,根节点没有父亲结点
二叉树具有天然递归结构,每个结点的左子树或右子树,也是一个二叉树
二叉树不一定是“满”的
极端的左或右都是二叉树,只不过退化成了线性表,这种情况称之为不平衡二叉

一个结点也叫二叉树,无非左右孩子都为null,null 空也是二叉树
什么是完全二叉树,什么是满二叉树,二叉树中层数与结点个数的关系?(自
查)
什么是二分搜索树?(Binary Search Tree)
二分搜索树是二叉树
对于二分搜索树的每个结点的值而言
大于其左子树的所有结点的值
小于其右子树的所有结点的值
其每一个子树也是二分搜索树
二分搜索树中所存储的元素必须具有可比较性!实现Comparable接口
不包含重复元素
------------------------------------------二分搜索树的实现:------------------------------------------------

**1.定义类**
public class BinarySearchTree<E extends Comparable<E>>{
**2.定义结点(内部类)**
private class Node{
    public E e;
    public Node left;
    public Node right;
    public Node(E e) {
    this.e=e;
    left=null;
    right=null;
    }
}
**3.定义成员变量**
private Node root;
private int size;
**4.定义构造函数**
public BinarySearchTree(){
    root=null;
    size=0;
}
**5.获取树中元素的个数**
public int size(){
	return size;
}
**6.判断树是否为空**
public boolean isEmpty(){
	return size==0;
}
**7.添加元素**
public void add(E e){
	root=add(root,e);
}
//以node为当前树的根节点,添加元素e并返回该树的根 此处递归实现
private Node add(Node node,E e){
if(node==null){ //如果根节点为null,则直接创建新节点,把e传进去;
	size++;
	return new Node(e);
}
if(e.compareTo(node.e)<0){ /
    node.left=add(node.left,e);
}else if(e.compareTo(node.e)>0){
	node.right=add(node.right,e);
}
	return node;
}
**8.查询元素**
public boolean contains(E e){
return contains(root,e);
}
//以node为根的树中是否包含元素e
private boolean contains(Node node,E e){
if(node==null){
return false;
}else if(e.compareTo(node.e)==0){
return true;
}else if(e.compareTo(node.e)<0){
return contains(node.left,e);
}else{
return contains(node.right,e);
}
}
**9.前序遍历(DLR)(深度优先遍历)**
public void preOrder(){
preOrder(root);
}
//前序遍历以node为根的树
private void preOrder(Node node){
if(node==null){
return;
}
System.out.println(node.e);
preOrder(node.left);
preOrder(node.right);
}
**10.中序遍历(LDR)(深度优先遍历)**
public void inOrder(){
inOrder(root);
}
//中序遍历以node为根的树
private void inOrder(Node node) {
if(node==null){
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
**11.后序遍历(LRD)(深度优先遍历)**
public void postOrder(){
postOrder(root);
}
//后序遍历以node为根的树
private void postOrder(Node node) {
if(node==null){
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.println(node.e);
}
**12.层序遍历(广度优先遍历)**
public void levelOrder(){
LinkedQueue<Node> queue=new LinkedQueue<Node>();
queue.enqueue(root);
while(!queue.isEmpty()){
Node cur=queue.dequeue();
System.out.println(cur.e);
if(cur.left!=null){
queue.enqueue(cur.left);
}
if(cur.right!=null){
queue.enqueue(cur.right);
}
}
}
**13.获取最小值**
public E minimum(){
if(size==0){
throw new IllegalArgumentException("Tree is empty!");
}
return minimum(root).e;
}
private Node minimum(Node node) {
if(node.left==null){
return node;
}else{
return minimum(node.left);
}
}
**14.获取最大值**
public E maximum(){
if(size==0){
throw new IllegalArgumentException("Tree is empty!");
}
return maximum(root).e;
}
private Node maximum(Node node) {
if(node.right==null){
return node;
}else{
return maximum(node.right);
}
}
**15.删除最小值**
public E removeMin(){
E ret=minimum();
root=removeMin(root);
return ret;
}
private Node removeMin(Node node) {
if(node.left==null){
Node rightNode=node.right;
node.right=null;
size­­;
return rightNode;
}
node.left=removeMin(node.left);
return node;
}
**16.删除最大值**
public E removeMax(){
E ret=maximum();
root=removeMax(root);
return ret;
}
private Node removeMax(Node node) {
if(node.right==null){
Node leftNode=node.left;
node.left=null;
size­­;
return leftNode;
}
node.right=removeMax(node.right);
return node;
}
**17.删除任意值**
public void remove(E e){
root=remove(root,e);
}
private Node remove(Node node, E e) {
if(node==null){
return null;
}
if(e.compareTo(node.e)<0){
node.left=remove(node.left,e);
return node;
}else if(e.compareTo(node.e)>0){
node.right=remove(node.right,e);
return node;
}else {
if(node.left==null){
Node rightNode=node.right;
node.right=null;
size­­;
return rightNode;
}
if(node.right==null){
Node leftNode=node.left;
node.left=null;
size­­;
return leftNode;
}
Node successor=minimum(node.right);
successor.right=removeMin(node.right);
successor.left=node.left;
node.left=node.right=null;
return successor;
}
}
**18.打印**
public String toString() {
StringBuilder res=new StringBuilder();
generateBSTString(root,0,res);
return res.toString();
}
private void generateBSTString(Node node, int
depth,StringBuilder res) {
if(node==null){
res.append(generateDepthString(depth)+"null\n");
return;
}
res.append(generateDepthString(depth)+node.e+"\n");
generateBSTString(node.left, depth+1, res);
generateBSTString(node.right, depth+1, res);
}
private String generateDepthString(int depth) {
StringBuilder res=new StringBuilder();
for (int i = 0; i < depth; i++) {
res.append("­­");
}
return res.toString();
}

19.拓展
二分搜索树具有顺序性(中序遍历就知道了,已经排好序了)
E floor(E e):查找小于元素e的最大值
E ceil(E e):查找大于元素e的最小值
int rank(E e):查找指定元素e的角标
E select(int index):查找指定角标index处的元素
允许重复元素怎么处理?直接加入,或者计数**

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值