Example #1
0
 void main()
 {
   RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
   SqList l;
   int i;
   for(i=0;i<N;i++)
     l.r[i+1]=d[i];
   l.length=N;
   printf("排序前:\n");
   print(l);
   TreeSort(l);
   printf("排序后:\n");
   print(l);
 }
int HierarchicalCluster(FILE* file, char metric, int transpose, char method)
{ int i;
  int ok = 0;
  const int nNodes = (transpose ? _columns : _rows) - 1;
  const double* order = (transpose==0) ? _geneorder : _arrayorder;
  double* weight = (transpose==0) ? _arrayweight : _geneweight;
  const char* keyword = (transpose==0) ? "GENE" : "ARRY";
 
  double* nodeorder = malloc(nNodes*sizeof(double));
  int* nodecounts = malloc(nNodes*sizeof(int));
  char** nodeID = calloc(nNodes, sizeof(char*));
  /* Perform hierarchical clustering. */
  Node* tree = treecluster(_rows, _columns, _data, _mask, weight, transpose,
                           metric, method, NULL);
  if (!tree || !nodeorder || !nodecounts || !nodeID)
  { if (tree) free(tree);
    if (nodeorder) free(nodeorder);
    if (nodecounts) free(nodecounts);
    if (nodeID) free(nodeID);
    return 0;
  }

  if (metric=='e' || metric=='b')
  /* Scale all distances such that they are between 0 and 1 */
  { double scale = 0.0;
    for (i = 0; i < nNodes; i++)
      if (tree[i].distance > scale) scale = tree[i].distance;
    if (scale) for (i = 0; i < nNodes; i++) tree[i].distance /= scale;
  }

  /* Now we join nodes */
  for (i = 0; i < nNodes; i++)
  { int min1 = tree[i].left;
    int min2 = tree[i].right;
    /* min1 and min2 are the elements that are to be joined */
    double order1;
    double order2;
    int counts1;
    int counts2;
    char* ID1;
    char* ID2;
    nodeID[i] = MakeID("NODE",i+1);
    if (!nodeID[i]) break;
    if (min1 < 0)
    { int index1 = -min1-1;
      order1 = nodeorder[index1];
      counts1 = nodecounts[index1];
      ID1 = nodeID[index1];
      tree[i].distance = max(tree[i].distance, tree[index1].distance);
    }
    else
    { order1 = order[min1];
      counts1 = 1;
      ID1 = MakeID(keyword, min1);
    }
    if (min2 < 0)
    { int index2 = -min2-1;
      order2 = nodeorder[index2];
      counts2 = nodecounts[index2];
      ID2 = nodeID[index2];
      tree[i].distance = max(tree[i].distance, tree[index2].distance);
    }
    else
    { order2 = order[min2];
      counts2 = 1;
      ID2 = MakeID(keyword, min2);
    }
 
    if (ID1 && ID2)
    { fprintf(file, "%s\t%s\t%s\t", nodeID[i], ID1, ID2);
      fprintf(file, "%f\n", 1.0-tree[i].distance);
    }
    if (ID1 && min1>=0) free(ID1);
    if (ID2 && min2>=0) free(ID2);
    if (!ID1 || !ID2) break;

    nodecounts[i] = counts1 + counts2;
    nodeorder[i] = (counts1*order1 + counts2*order2) / (counts1 + counts2);
  }

  if (i==nNodes) /* Otherwise we encountered the break */
  { /* Now set up order based on the tree structure */
    const char which = (transpose==0) ? 'g' : 'a';
    ok = TreeSort(which, nNodes, order, nodeorder, nodecounts, tree);
  }
  free(nodecounts);
  free(nodeorder);
  for (i = 0; i < nNodes; i++) if (nodeID[i]) free(nodeID[i]);
  free(nodeID);
  free(tree);

  return ok;
}