【问题标题】:Optimal Binary Search Trees最优二叉搜索树
【发布时间】:2011-09-30 23:06:08
【问题描述】:

我有一个关于最佳二叉搜索树的作业,在做的时候出现了一些问题。我发现许多在线链接很有帮助(仅来自 Google 搜索),但我想知道...

为什么必须对键进行初始排序?

如果我在未对键进行排序时获得较低的成本(对于最佳 BST),这是否意味着我的代码中一定有错误?

最佳 BST 必须是完整/完美的吗? (使用维基百科对完整和完美的定义)

完美二叉树是一棵完整的二叉树,其中所有叶子都处于相同的深度或相同的级别。 [1] (这也有歧义地称为完全二叉树。)

完全二叉树是一种二叉树,其中除了可能的最后一层之外,每一层都被完全填满,并且所有节点都尽可能靠左。 [2]

对于最后一个问题,我认为最优树必须是完整/完美的,但网上的一些小程序让我不这么认为。我无法解释为什么......

【问题讨论】:

    标签: data-structures binary-search-tree


    【解决方案1】:

    为什么必须对键进行初始排序?

    他们没有。事实上,除非您使用自平衡树,否则最好以随机顺序将键添加到树中,因为树最终会更加平衡。

    如果我在未对键进行排序时获得较低的成本(对于最佳 BST),这是否意味着我的代码中一定有错误?

    除非您正在编写自平衡树(您的自平衡算法不起作用),否则不会。

    最佳 BST 必须是完整/完美的吗?

    是的。为了尽可能快地搜索给定的树,树的所有节点必须均匀分布;即树必须尽可能短。

    【讨论】:

    • 我没有使用自平衡树。这是否意味着最优树不是唯一的(假设唯一键)或树(前面提到的使用排序键生成的)不是最优的?
    • 非平衡二叉树按排序顺序插入键不是最优的,因为键不会均匀分布。相反,您将获得一个链表,因为所有键都将插入树的一侧。 jaltiere.com/blogImages/redblacktree/binarysearchtree.png
    • 好的。我明白你告诉我的一切,我现在已经查明了我的问题。虽然看起来大多数在线小程序实际上根本没有生成最优树(linneus20.ethz.ch:8080/4_7_2.html)例如,使用 2,9 和 11 作为键应该最优地生成以 11 为根的树,但我将此作为最佳结果(9 是根)postimage.org/image/fm8qsgkk 我还不确定如何解决这个问题。除非我的逻辑有缺陷。
    • 没关系。右侧数字较大,左侧数字较小。
    【解决方案2】:
    void OptimalBinsearchtree_output(float R[21][20],int i, int j, int r1, char  *dir)
    {
              int t;
              if (i <= j)
              {
                             t =(int)R[i][j];
                             fprintf(wp,"%s is %s child of %s\n", name[t], dir, name[r1]);
                             OptimalBinsearchtree_output(R,i, t - 1, t, "left");
                             OptimalBinsearchtree_output(R,t + 1, j, t, "right");
              }
    }
    
    void OptimalBinarySearchTree(int n, const float p[],float *minavg)
    {
              int i, j, k, diagonal,l,pos;
              float R[21][20];
              float min = 0;
              float A[21][20],sum=0;
              printf("\n");
              for (i = 1; i <=n; i++) 
              {
                             A[i][i - 1] = 0;
                             R[i][i - 1] = 0;
                             A[i][i] = p[i];
                             R[i][i] = i;
                             fprintf(wp,"A[%d][%d]=%4f\tA[%d][%d]=%4f\t",i,i-1,A[i][i-1],i,i,A[i][i]);
                             fprintf(wp,"R[%d][%d]=%4f\tR[%d][%d]=%4f\n", i, i - 1, R[i][i - 1], i, i, R[i][i]);
              }
    
              A[n+1][n] = 0;
              R[n+1][n] = 0;
              for (diagonal = 1; diagonal <= n - 1; diagonal++)
              {
                             for (i = 1; i <= n - diagonal; i++)
                             {
                                           min = 0;
                                           sum = 0;
                                           j = i + diagonal;
                                           for (l = i; l <=j; l++)
                                           {
                                                          sum = sum + p[l];
                                           }
                                           A[i][j] = sum;
                                           for (k = i; k <= j; k++)
                                           {
                                                          sum = A[i][k - 1] + A[k + 1][j];
                                                          if (min == 0)
                                                          {
                                                                        min = sum;
                                                                        pos = k;
                                                          }
                                                          else if (sum<min)
                                                          {
                                                                        min = sum;
                                                                        pos = k;
                                                          }
                                           }
                                           A[i][j] += min;
                                           R[i][j] = pos;
                             }
              }
    
              *minavg = A[1][n];
              printf("\n");
              for (i = 1; i <= n; i++)
              {
                             for (j = 0; j <= n; j++)
                             {
                                           printf("%0.3f ", R[i][j]);
                             }
                             printf("\n");
              }
              for (i = 1; i <= n; i++)
              {
                             for (j = 0; j <= n; j++)
                             {
                                           printf("%0.3f ", A[i][j]);
                             }
                             printf("\n");
              }
              fprintf(wp,"\n\n");
              fprintf(wp,"%s is the root of the tree\n",name[(int)R[1][n]]);
              int r1 = (int)R[1][n];
              OptimalBinsearchtree_output(R,1, r1 - 1, r1, "left");
              OptimalBinsearchtree_output(R,r1 + 1, n, r1, "right");
    
    }
    
    
    void removeall()
    {
              nodeptr node,temp;
              node = head;
              while (node->next != NULL)
              {
                             temp = node;
                             node = node->next;
              }
              if (node == node->next)
              {
                             node->next = NULL;                     
                             temp->next = NULL;
                             free(node);
                             return;
              }
              node->next = NULL;
              temp->next = NULL;
              free(node);
    }
    
    void print()
    {
              nodeptr curr = NULL, temp = NULL;
              curr = head;
              gl_index = 1;
              while (curr != NULL)
              {
    
                             curr->index = gl_index;
                             gl_p[gl_index] = curr->val;
                             strcpy(name[gl_index], curr->str);
                             gl_index++;
                             wp=fopen("Output.txt","w+");
                             fprintf(wp,"%s\t%f\t%d\n", curr->str, curr->val, curr->index);
                             curr = curr->next;
              }
    }
    
    
    void generatenode()
    {
    
    
              int i, j;
              nodeptr temp = NULL;
              char a[20];
    
              while (!feof(fp))
              {
                             nodeptr curr = NULL, prev = NULL;
                             temp = (struct node*)malloc(sizeof(struct node));
                             fscanf(fp, "%s", &temp->str);
                             fgets(a, 20, fp);
                             temp->index = gl_index;
                             b = atof(a);
                             int flag = 0;
                             temp->val = b;
                             gl_p[gl_index] = temp->val;
                             gl_index++;
                             temp->next = NULL;
                             if (head == NULL)
                             {
                                           head = temp;
                                           curr = head;
                             }
                             else
                             {
                                           curr = head;
                                           while (!(strcmp(temp->str, curr->str) < 0))
                                           {
                                                          if(curr->next==NULL)
                                                          {
                                                                        curr->next = temp;
                                                                        curr = curr->next;
                                                                        temp->next = NULL;
                                                                        flag = 0;
                                                                        break;
                                                          }
                                                          else
                                                          {
                                                                        flag = 1;
                                                                        prev = curr;
                                                                        curr = curr->next;
                                                          }
                                           }
                                           if (curr == head)
                                           {
                                                          temp->next = curr;
                                                          head = temp;
                                           }
                                           else
                                           {
                                                          if (flag == 1)
                                                          {
                                                          prev->next = temp;
                                                          temp->next = curr;
                                                          }
                                           }
                                           flag = 0;
                             }
              }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      相关资源
      最近更新 更多