Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 最优二叉搜索树错误输出_C_Algorithm_Dynamic Programming - Fatal编程技术网

C 最优二叉搜索树错误输出

C 最优二叉搜索树错误输出,c,algorithm,dynamic-programming,C,Algorithm,Dynamic Programming,我正在研究一个问题,通过尽可能最好地安排二叉搜索树,来计算二叉搜索树中所需的最小遍历次数。我确实在网上遇到了一个解决方案,我已经理解了,但我手工计算了一些样本输入,并没有得到正确的结果 下面是代码 #include <stdio.h> #include <limits.h> // A utility function to get sum of array elements freq[i] to freq[j] int sum(int freq[], int i, in

我正在研究一个问题,通过尽可能最好地安排二叉搜索树,来计算二叉搜索树中所需的最小遍历次数。我确实在网上遇到了一个解决方案,我已经理解了,但我手工计算了一些样本输入,并没有得到正确的结果

下面是代码

#include <stdio.h>
#include <limits.h>

// A utility function to get sum of array elements freq[i] to freq[j]
int sum(int freq[], int i, int j);

/* A Dynamic Programming based function that calculates minimum cost of
   a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)
{
    /* Create an auxiliary 2D matrix to store results of subproblems */
    int cost[n][n];

    /* cost[i][j] = Optimal cost of binary search tree that can be
       formed from keys[i] to keys[j].
       cost[0][n-1] will store the resultant cost */

    // For a single key, cost is equal to frequency of the key
    for (int i = 0; i < n; i++)
        cost[i][i] = freq[i];

    // Now we need to consider chains of length 2, 3, ... .
    // L is chain length.
    for (int L=2; L<=n; L++)
    {
        // i is row number in cost[][]
        for (int i=0; i<=n-L+1; i++)
        {
            // Get column number j from row number i and chain length L
            int j = i+L-1;
            cost[i][j] = INT_MAX;

            // Try making all keys in interval keys[i..j] as root
            for (int r=i; r<=j; r++)
            {
               // c = cost when keys[r] becomes root of this subtree
               int c = ((r > i)? cost[i][r-1]:0) + 
                       ((r < j)? cost[r+1][j]:0) + 
                       sum(freq, i, j);
               if (c < cost[i][j])
                  cost[i][j] = c;
            }
        }
    }
    return cost[0][n-1];
}

// A utility function to get sum of array elements freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
    int s = 0;
    for (int k = i; k <=j; k++)
       s += freq[k];
    return s;
}

// Driver program to test above functions
int main()
{
    int keys[] = {10, 12, 20};
    int freq[] = {34, 8, 50};
    int n = sizeof(keys)/sizeof(keys[0]);
    printf("Cost of Optimal BST is %d ", optimalSearchTree(keys, freq, n));
    return 0;
}
#包括
#包括
//获取数组元素freq[i]到freq[j]之和的实用函数
整数和(整数频率[],整数i,整数j);
/*一种基于动态规划的函数,用于计算
二叉搜索树*/
整数优化搜索树(整数键[],整数频率[],整数n)
{
/*创建辅助二维矩阵以存储子问题的结果*/
国际成本[n][n];
/*cost[i][j]=二叉搜索树的最佳成本
由键[i]到键[j]构成。
成本[0][n-1]将存储结果成本*/
//对于单个密钥,成本等于密钥的频率
对于(int i=0;i对于(int L=2;L您对预期结果的理解是错误的。以您的第一个示例为例,使用键
{1,2,3}
和频率
{10,3,1}
;最佳二进制搜索树是:

1 (10) \ 2 (3) \ 3 (1) 成本为
(200*1)+(5*2)+(4*3)+(1*4)=226

使用键
{1,2,3,4,5,6}
和频率
{33,1409,2,1,34}

3 (409) / \ / \ 1 (33) 6 (34) \ / 2 (1) 4 (2) \ 5(1) 3 (409) / \ / \ 1 (33) 6 (34) \ / 2 (1) 4 (2) \ 5(1) 成本
(409*1)+(33+34)*2)+(1+2)*3)+(1*4)=556

程序在每种情况下都返回正确的结果


我把20个关键点的例子留给你作为练习。这种情况下有多个最佳搜索树,但正如程序所给出的那样,所有的搜索树都花费了532英镑。

你能解释一下这些值
关键点
频率
代表了什么,以及你试图应用的算法吗?@chmike这是你使用debu时的一个很好的来源gger和single逐步浏览代码,哪些行出现问题?对于这种情况:int-keys[]={1,2,3};int-freq[]={10,3,1};结果应该是19假设您有三个项,A、B和C。您搜索A 10次、B 3次和C 1次。您可以将它们排列为A在左分支上,B和C在右分支上成对排列。就处理所有搜索所需遍历的边的数量而言,单个边有10次遍历才能到达A、A然后对边进行4次遍历以到达B和C对,然后沿边向下3次遍历到B,沿边向下1次遍历到C。此树的边遍历总数为10+4+3+1,或18。假设您有三个术语,A、B和C。您搜索10次、B3次和C1次。您可以使用左分支上的A以及B和C来排列它们作为右分支上的一对。就处理所有搜索所需遍历的边数而言,有10次遍历一条边才能到达a,然后4次遍历边才能到达B和C对,然后3次遍历边才能到达B,1次遍历边才能到达C。此树的边遍历总数为10+4+3+1或18。@user2733436,该程序计算节点访问次数,这是一个有效的成本度量。当且仅当在计数中包含根节点的传入边时(这样做是有意义的,否则搜索存储在根节点中的密钥是免费的),这相当于计算边遍历次数。忽略树的根节点和右侧子节点中存储了哪些键的问题,搜索它所需的节点访问次数为(10*2)+((4+3)*3)=56,比我给出的树糟糕得多。@user2733436,即使您计算边遍历次数,即使您没有计算到达根的边遍历次数,您对树的计算也是错误的。您必须为每个键A的搜索计算1次边遍历,为每个键B或C的搜索计算2次边遍历——一次从根到其右侧子级,另一次从右到右om到目标节点。这使得10+(4+3)*2=24,仍然比我的树更糟糕(如果这样计算的话,值为18)@user2733436,无论如何,问题是为什么程序的输出不符合OP的期望,我已经用程序正在做的准确描述回答了这个问题。你可以随意不同意它使用的成本度量,但这与问题无关。@user2733436,我明确给出了数字搜索树涉及的节点访问次数,当然是19次,如我所说。答案中给出了计算。这也是搜索树所需的边遍历次数,假设您将传入边计算到根节点。如果不将传入边计算到根节点,则搜索成本为
(10*0)+(3*1)+(1*2)=5
。 3 (409) / \ / \ 1 (33) 6 (34) \ / 2 (1) 4 (2) \ 5(1)