二叉樹計算帶權路徑長度(WPL)的算法
更多內容請訪問點擊我的主頁
- 題目 :
-
二叉樹的帶權路徑長度是二叉樹中所有葉子結點的帶權路徑長度之和。給定二叉鏈表的存儲的結點結構爲
left weight right -
weight存儲的是葉子結點的非負權值。設計算法求二叉樹的帶權路徑長度WPL。
WPL = ∑ 葉子結點的權值 × 結點到根結點的分支個數 1
例如:
非遞歸算法
- 算法思想:根據公式,需要記錄每個結點到根結點的分支個數,這個過程通過對樹進行廣度遍歷(藉助隊列)進行記錄。
在非葉子結點weight初值爲-1,葉子結點初值設爲非負權值。
最後對隊列進行逐個訪問,如果weight != -1,那就計算該點。
wpl += (Q[i].p->weigth) * (Q[i].p->lno - 1); //WPL公式代碼
這裏改造隊列的結點結構
typedef struct
{
LBTree* p; //樹的結點
int lno; //結點深度
}Queue;
- 僞代碼
typedef struct
{
LBTree* p;
int lno;
}Queue;
int WPL(LBTree* lbt)
{
Queue Q[maxSize];
int front,rear;
front = rear = 0;
int Lno = 1;
LBTree* q = lbt;
Q[rear].p = q;
Q[rear].lno = Lno;
rear++;
while (front != rear)
{
q = Q[front].p;
Lno = Q[front].lno;
front++;
if (q->lchild != NULL)
{
Q[rear].p = q->lchild;
Q[rear].lno = Lno + 1;
rear++;
}
if (q->rchild != NULL)
{
Q[rear].p = q->rchild;
Q[rear].lno = Lno + 1;
rear++;
}
}
int wpl = 0;
for (int i = 0; i < rear; i++)
{
if (Q[i].p->weigth != -1)
wpl += (Q[i].p->weigth) * (Q[i].p->lno - 1);
}
return wpl;
}
遞歸算法 (推薦)
- 算法描述:本算法採用的是統計葉子結點算法基礎上改造而來的。只是在參數列表定義了結點到根的分支個數。進行一個遞歸計算。統計結點數在個人主頁有相關算法。
- 代碼如下:
int WPLrec(LBTree* lbt,int n)
{
int wpl = 0;
if (lbt != NULL)
{
if (lbt->lchild == NULL && lbt->rchild == NULL)
wpl += n * lbt->weigth;
wpl += WPLrec(lbt->lchild, n + 1);
wpl += WPLrec(lbt->rchild, n + 1);
}
return wpl;
}
結點到根結點的分支個數 = 該結點的深度 - 1。 ↩︎