次優二叉樹


原理

首先取出查找表中每個關鍵字及其對應的權值,采用如下公式計算出每個關鍵字對應的一個值:

file

其中 wj 表示每個關鍵字的權值(被查找到的概率),h 表示關鍵字的個數。

表中有多少關鍵字,就會有多少個 △Pi ,取其中最小的做為次優查找樹的根結點,然后將表中關鍵字從第 i 個關鍵字的位置分成兩部分,分別作為該根結點的左子樹和右子樹。同理,左子樹和右子樹也這么處理,直到最后構成次優查找樹完成。

typedef int KeyType;//定義關鍵字類型
typedef struct{
    KeyType key;
}ElemType;//定義元素類型
typedef struct BiTNode{
    ElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//定義變量
int i;
int min;
int dw;
//創建次優查找樹,R數組為查找表,sw數組為存儲的各關鍵字的概率(權值),low和high表示的sw數組中的權值的范圍
void SecondOptimal(BiTree T, ElemType R[], float sw[], int low, int high){
    //由有序表R[low...high]及其累計權值表sw(其中sw[0]==0)遞歸構造次優查找樹
    i = low;
    min = abs(sw[high] - sw[low]);
    dw = sw[high] + sw[low - 1];
    //選擇最小的△Pi值
    for (int j = low+1; j <=high; j++){
        if (abs(dw-sw[j]-sw[j-1])<min){
            i = j;
            min = abs(dw - sw[j] - sw[j - 1]);
        }
    }
   
    T = (BiTree)malloc(sizeof(BiTNode));
    T->data = R[i];//生成結點(第一次生成根)
    if (i == low) T->lchild = NULL;//左子樹空
    else SecondOptimal(T->lchild, R, sw, low, i - 1);//構造左子樹
    if (i == high) T->rchild = NULL;//右子樹空
    else SecondOptimal(T->rchild, R, sw, i + 1, high);//構造右子樹
   
}

完整事例演示

例如,一含有 9 個關鍵字的查找表及其相應權值如下表所示:
file
則構建次優查找樹的過程如下:首先求出查找表中所有的 △P 的值,找出整棵查找表的根結點:

例如,關鍵字 F 的 △P 的計算方式為:從 G 到 I 的權值和 - 從 A 到 E 的權值和 = 4+3+5-1-1-2-5-3 = 0。

通過上圖左側表格得知,根結點為 F,以 F 為分界線,左側子表為 F 結點的左子樹,右側子表為 F 結點的右子樹(如上圖右側所示),繼續查找左右子樹的根結點:file

通過重新分別計算左右兩查找子表的 △P 的值,得知左子樹的根結點為 D,右子樹的根結點為 H (如上圖右側所示),以兩結點為分界線,繼續判斷兩根結點的左右子樹:file
通過計算,構建的次優查找樹如上圖右側二叉樹所示。后邊還有一步,判斷關鍵字 A 和 C 在樹中的位置,最后一步兩個關鍵字的權值為 0 ,分別作為結點 B 的左孩子和右孩子,這里不再用圖表示。

注意:在建立次優查找樹的過程中,由於只根據的各關鍵字的 P 的值進行構建,沒有考慮單個關鍵字的相應權值的大小,有時會出現根結點的權值比孩子結點的權值還小,此時就需要適當調整兩者的位置。
歡迎瀏覽我的主頁


免責聲明!

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



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