寻找最近的祖先

时间:2014-07-24 18:45:56

标签: javascript

我遇到了一个我想弄明白的问题,希望有人可以提供帮助。输入是这样的:

{
    "John": ["Sam", "Megan"],
    "Sam": ["Donna", "Josh", "Flora"],
    "Megan": ["Stephanie", "Nathan"]
}

Sam和Megan是John的孩子等等。我需要找到最接近2个名字的祖先。例如,Sam和Josh将返回Sam,Donna和Josh将返回Sam,等等。我已经完成了那部分,但问题是如果他们开始移动结构,所以不是在上面,他们将其改为:

{
    "Sam": ["Donna", "Josh", "Flora"],
    "Megan": ["Stephanie", "Nathan"],
    "John": ["Sam", "Megan"]
}

然后我的代码有问题。有人可以给我一些暗示吗?我的JavaScript知识非常基础,所以如果有人可以帮助它,那就很棒。

2 个答案:

答案 0 :(得分:1)

观察血统和家谱是字面上检查树结构。因此,可以利用一些相似之处。在树形式中,它将是深度。在这个沿袭模型中,它将是世代号。请注意,您已经在逻辑上执行此操作(基于索引)。现在你只需要具体化。

我不确定你是如何最好地编写这些内容的。但是当您知道顺序时,就是需要将其添加到数组中或将其包装在对象中。

数组版本

{
 "Sam": [2,"Donna", "Josh", "Flora"],
 "Megan": [2,"Stephanie", "Nathan"],
 "John": [1,"Sam", "Megan"]
}

对象版本

{
 "Sam": {"generation":2,"children":["Donna", "Josh", "Flora"]},
 "Megan": {"generation":2,"children":["Stephanie", "Nathan"]},
 "John": {"generation:1","children":["Sam", "Megan"]}
}

或者更优选的版本是为家族行分配某种唯一标识符,以便您也可以区分它们。

{
 "Sam": {
  "family":"f31460e9",
  "generation":2,
  "children":["Donna", "Josh", "Flora"]
 },
 "Megan": {
  "family":"f31460e9",
  "generation":2,
  "children":["Stephanie", "Nathan"]},
 "John": {
  "family":"f31460e9",
  "generation:1",
  "children":["Sam", "Megan"]
 }
}

答案 1 :(得分:0)

我的回答是基于最常见的祖先算法,可以很容易地研究。它假定您知道整个树根的人的名字。它基本上递归地搜索树,寻找包含两个元素的最低节点。 Here is a JSFiddle containing a few names.希望这有帮助。

function findAncestor(root, p1, p2) {
   if(!root)
      return "";

   if(root == p1 || root == p2)
      return root;
   else
   {
      var count = 0;
      var lastfound = -1;
      if(fam[root]) //make sure root exists in fam
      {
          for(var i = 0; i < fam[root].length; i++)
          {
              var res = findAncestor(fam[root][i], p1, p2); //recursively search trees
              if(res)
              {
                  count++;
                  lastfound = i;
              }
          }
      }

      if(count >= 2) //found in different subtrees so this is the ancestor
         return root;
      else if(count == 1)
          return fam[root][lastfound];
      else
          return "";
   }
}