[ハフマン木] fast_wpl 加重パス長の高速計算

wpl: 加重パス長。加重パス長を指します。

        一連の重みに対応するハフマン ツリーの重み付きパスの長さを見つけるための最も直接的な方法は、最初にハフマン ツリーを構築し、次にすべてのリーフ ノードの重み付きパスの合計を計算することです。

gif.latex?wpl%28T%29%3D%5C%3B%20%5Csum_%7Bk%7D%5CL_%7Bk%7D*w_%7Bk%7D

        この解決策では、最初にハフマン ツリーを構築し、次に各リーフ ノードに対応する深さをマークし、次にすべてのリーフ ノードを走査する必要があります。

        しかし実際には、wpl を解くだけであれば、ハフマン ツリーを構築する必要はなく、深さを解決してリーフ ノードを走査する必要はありません。元のノードと新しく生成されたノードの最小重みを繰り返し加算するだけで済みます

最初にコードを指定します: (デフォルトの重み配列は順序付けされています)

//默认权重数组w已经有序(从小到大)
//指针p指向当前最小权值的index,初始值给1
//n为数组w的规模
//权重数组w默认1为起始位
int ans=0;
int fastwpl(int w[],int p,int n)   
{
    if(n<=1) return 0;        //没有或只有一个节点,wpl为0;
	if (p>= n) return ans;    //当p指向最末位(根节点),求解结束
	else {
		int new_w = w[p] + w[p+1];  //取出两个最小权值,生成新权值
		ans += new_w;               
		//插入新权值节点//
        //查找插入位置
		int i = p+2;        //由于两个最小权值已取出,所以从p+2开始检索
		while (new_w > w[i] && i<=n ) i++;
		//在i之前插入新权值
		for (int j = p + 1; j < i-1; j++) w[j] = w[j + 1];
		w[i - 1] = new_w;
        //指针后移一位(每次运算,删除两个最小节点,生成一个新节点,故p+1)
		p++;
		fastwpl(w, p, n);
	}
}

アルゴリズムの説明 (次の図のハフマン ツリーは例です):                 

5af8b3a04d434f03917ae7e0bcfa58df.png

最も簡単な解決策は次のとおりです。

                                        gif.latex?wpl%3D2*3+4*3+5*2+7*1%3D35

この記事の解決策は次のとおりです。

                ​​​​​​​ ​​​​​​​ ​​​​​​​        gif.latex?wpl%3D2+4+5+6+7+11%3D35

つまり、ルート以外のすべてのノードの重みを合計します。

        この解決策は不合理に思えます。ノードの経路長がまったく考慮されていないように見えます。実際、「パス長」、つまりリーフの深さの計算は、中間ノードの繰り返しの合計プロセスに暗黙的に含まれます。

たとえば、ノード 2 と 4 の経路長は 3、つまり重み付けされた経路長は 2*3+4*3 であり、2 と 4 を 3 回繰り返し加算することに相当します。

        別の考え方では、2 + 4 で構成される新しいノード 6 を追加すると、そのペアに対して +2+4 演算を実行するのと同じになります。

つまり、+2+4+6=+2+4+(2+4)=+2*2+4*2 となります。

        同様に、次の演算層では、6 + 5 によって得られる新しいノード 11 を追加することは、6 = 2 + 4 を再度追加することと同じです。

        したがって、新しいノードを継続的に追加するプロセスでは、リーフ ノード 2 と 4 のパス長を継続的に反復することと同じになります。

一般に、次のように結論付けることができます。

       wpl=ハフマンツリーのすべての非ルートノードの重みの合計を生成します

        したがって、一連の重みの最小重み付きパス長を計算するには、リーフ ノードとその新しく生成された重みノードを繰り返し追加するだけで済みます。重み配列が順序付けされている場合、複雑さは O(n) です。

        ソートに関しては、クイックソートまたはマージソートを使用できます。

 

 

 

おすすめ

転載: blog.csdn.net/m0_67441224/article/details/127479614