java实现二分检索_二分搜索树的java实现

标签:minimum   sem   mini   oid   pos   turn   else   min()   rgs

递归理解起来还是有点难,弄清楚搞了不短的时间

package com.puple.atto.datastructure;

import java.util.LinkedList;

import java.util.Queue;

public class BST> {

private class Node{

public E e;

public Node left,right;

public Node(E e){

this.e=e;

left=null;

right=null;

}

public Node(E e,Node left,Node right){

this.e=e;

this.left=left;

this.right=right;

}

@Override

public String toString() {

return "" this.e;

// return "value:" this.e ",left:" this.left.e ",rigth:" this.right.e;

}

}

private Node root;

private int size;

public BST(){

root=null;

size=0;

}

public int size(){

return size;

}

public boolean isEmpty(){

return size==0;

}

private Node add(Node node,E e){

if (node==null){

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;

}

public void add(E e){

root=add(root,e);

}

private boolean contains(Node node,E e){

if (node==null){

return false;

}

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);

}

}

public boolean contains(E e){

return contains(root,e);

}

public void preOrder(){

preOrder(root);

}

private void preOrder(Node node){

if (node==null){

return;

}

System.out.println(node.e);

preOrder(node.left);

preOrder(node.right);

}

public void inOrder(){

inOrder(root);

}

private void inOrder(Node node){

if(node==null){

return;

}

inOrder(node.left);

System.out.println(node.e);

inOrder(node.right);

}

public void postOrder(){

postOrder(root);

}

private void postOrder(Node node){

if(node==null){

return;

}

postOrder(node.right);

System.out.println(node.e);

postOrder(node.left);

}

public void levelOrder(){

Queue q=new LinkedList<>();

q.add(root);

while(!q.isEmpty()){

Node cur=q.remove();

System.out.println(cur.e);

if (cur.left!=null){

q.add(cur.left);

}

if (cur.right!=null){

q.add(cur.right);

}

}

}

public E minimum(){

if(size==0){

throw new IllegalArgumentException("BST is empty");

}

return minimum(root).e;

}

private Node minimum(Node node){

if(node.left==null){

return node;

}

return minimum(node.left);

}

public E maximum(){

if(size==0){

throw new IllegalArgumentException("BST is empty.");

}

return maximum(root).e;

}

private Node maximum(Node node){

if (node.right==null){

return node;

}

return maximum(node.right);

}

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;

}

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=removeMin(node.right);

return node;

}

// 从二分搜索树中删除元素为e的节点

public void remove(E e){

root = remove(root, e);

}

// 删除掉以node为根的二分搜索树中值为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{ // e.compareTo(node.e) == 0

// 待删除节点左子树为空的情况

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;

}

}

public static void main(String[] args) {

BST bst=new BST();

bst.add(1);

bst.add(8);

bst.add(-1);

bst.add(9);

bst.add(-5);

bst.add(-10);

bst.add(-3);

bst.add(17);

bst.add(100);

bst.add(-75);

bst.add(-90);

bst.add(-80);

bst.add(120);

// System.out.println(bst.root.e);

// System.out.println(bst.contains(9));

// bst.preOrder();

// bst.inOrder();

// bst.postOrder();

}

}

二分搜索树的java实现

标签:minimum   sem   mini   oid   pos   turn   else   min()   rgs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二分搜索(Binary Search Tree)是一种基于二分查找的数据结构,它的左子中的所有节点都小于根节点,右子中的所有节点都大于根节点。最优二分搜索(Optimal Binary Search Tree)也称为哈夫曼(Huffman Tree),是一种带权路径最短的二叉,它的带权路径长度最小,也就是说,它的各个叶子节点的深度加上其权值的乘积之和最小。 以下是用Java代码实现最优二分搜索的示例: ```java public class OptimalBST { private static final int INF = Integer.MAX_VALUE; private static int n; private static int[] p; private static int[] q; private static int[][] w; private static int[][] e; private static int[][] root; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入节点数:"); n = scanner.nextInt(); p = new int[n + 1]; q = new int[n + 1]; System.out.println("请输入节点的概率:"); for (int i = 1; i <= n; i++) { p[i] = scanner.nextInt(); } System.out.println("请输入虚拟节点的概率:"); for (int i = 0; i <= n; i++) { q[i] = scanner.nextInt(); } w = new int[n + 2][n + 2]; e = new int[n + 2][n + 2]; root = new int[n + 1][n + 1]; optimalBST(); System.out.println("最优二叉搜索的带权路径长度为:" + e[1][n]); } private static void optimalBST() { // 初始化 w、e、root 数组 for (int i = 1; i <= n + 1; i++) { w[i][i - 1] = q[i - 1]; e[i][i - 1] = q[i - 1]; } for (int len = 1; len <= n; len++) { for (int i = 1; i <= n - len + 1; i++) { int j = i + len - 1; e[i][j] = INF; w[i][j] = w[i][j - 1] + p[j] + q[j]; for (int k = i; k <= j; k++) { int t = e[i][k - 1] + e[k + 1][j] + w[i][j]; if (t < e[i][j]) { e[i][j] = t; root[i][j] = k; } } } } } } ``` 该代码中,使用了动态规划的思想,通过计算每个子的带权路径长度,逐步求得最优二叉搜索的带权路径长度。在计算过程中,使用了一个 root 数组,记录了每个子的根节点。最后,根据 root 数组和节点的概率,可以构建出最优二叉搜索
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值