算法筆記_053:最優二叉查找樹(Java)


目錄

1 問題描述

2 解決方案

 


1 問題描述

在了解最優二叉查找樹之前,我們必須先了解何為二叉查找樹?

引用自百度百科一段講解:

二叉排序樹(Binary Sort Tree)又稱二叉查找樹Binary Search Tree),亦稱二叉搜索樹

二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹

1)若左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值;

2)若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值;

3)左、右子樹也分別為二叉排序樹;

在二叉查找樹的基礎上,引出了一個最優二叉查找樹的問題:它在查找樹中所有節點的平均鍵值比較次數是最低的。PS:如若對於最優二叉查找樹的定義理解還是有點模糊,可以參考本文最后給出的參考資料中的鏈接)

 


2 解決方案

本文具體編碼思想參考自《算法設計與分析基礎》第三版,具體如下(PS:對於文中的具體思想,樓主自己是前后看了三四遍才整明白其具體思想,竟無語吟噎......,如若對於下面貼出的書中介紹無法理解,可以參考文末給出的參考資料的鏈接中,一位網友的博客講解哦):

 

 

具體代碼如下:

package com.liuzhen.chapter8;

public class OptimalBST {
    /*
     * 參數P:表示1~n個節點的查找概率。其中P[0] = 0,無意義
     * 函數功能:返回在最優BST中查找的平均比較次數主表C[][],以及最優BST中子樹的根表R
     */
    public void getBestTree(double[] P) {
        int lenP = P.length;
        double[][] C = new double[lenP+1][lenP];   //保存最有BST的成功查找的平均比較次數
        int[][] R = new int[lenP+1][lenP];   //保存最優BST中子樹的根表R
        for(int i = 1;i < lenP;i++) {
            C[i][i] = P[i];
            R[i][i] = i;
        }
        
        for(int d = 1;d < lenP-1;d++) {
            for(int i = 1;i < lenP-d;i++) {
                int j = i + d;
                double minval = Double.MAX_VALUE;     //以double類型的最大值,表示minval趨向無窮大
                int kmin = 0;
                for(int k = i;k <= j;k++) {
                    if(C[i][k-1] + C[k+1][j] < minval) {
                        minval = C[i][k-1] + C[k+1][j];
                        kmin = k;
                    }
                }
                R[i][j] = kmin;
                double sum = P[i];
                for(int s = i+1;s <= j;s++)
                    sum += P[s];
                C[i][j] = minval + sum;
            }
        }
        
        System.out.println("在最優BST中查找的平均比較次數依次為:");
        for(int i = 1;i < C.length;i++) {
            for(int j = 0;j < C[0].length;j++)
                System.out.printf("%.1f\t",C[i][j]);
            System.out.println();
        }
        
        System.out.println("在最優BST中子樹的根表R為:");
        for(int i = 1;i < R.length;i++) {
            for(int j = 0;j < R[0].length;j++)
                System.out.print(R[i][j]+"\t");
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        OptimalBST test = new OptimalBST();
        double[] P = {0,0.1,0.2,0.4,0.3};
        test.getBestTree(P);
    }
    
}

運行結果:

在最優BST中查找的平均比較次數依次為:
0.0    0.1    0.4    1.1    1.7    
0.0    0.0    0.2    0.8    1.4    
0.0    0.0    0.0    0.4    1.0    
0.0    0.0    0.0    0.0    0.3    
0.0    0.0    0.0    0.0    0.0    
在最優BST中子樹的根表R為:
0    1    2    3    3    
0    0    2    3    3    
0    0    0    3    3    
0    0    0    0    4    
0    0    0    0    0    

 

 

 

參考資料:

   1.《算法設計與分析基礎》第3版  Anany Levitin 著 潘彥 譯

   2.動態規划方法生成最優二叉查找樹

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM