【问题标题】:Reading an array 'from left to right', binary heap priority读取数组'从左到右',二进制堆优先级
【发布时间】:2016-06-28 13:14:43
【问题描述】:

我有一段简单的代码可以读取一组值。在用户输入时,比较 2 个值并将其设置为二进制堆。该方法在此处描述:

http://foswiki.cs.uu.nl/foswiki/MethodEngineering/TheBinarySearchTreeAsRequirementsPrioritizationTechnique

彼得将每个要求写在一张纸上,然后将它们堆积起来。在一个 第二步,他从 堆放在白板上。然后他又拿了一个 需求(需求7)从堆和小组讨论 哪个要求(要求 5 或 7)更重要。最后他们 同意要求 7 不如要求 5 重要。 Peter 把要求 7 放在要求 5 的左下角。然后他拿 另一个要求(要求 4),小组再次比较 与要求 5. 在得出结论之后,它也更少 比要求 5 重要,他们将其与要求 7 进行比较。他们 同意它比要求 7 更重要。彼得提出 要求 4 在要求 7 的右下角。小组重复 此程序适用于对桩的所有要求。最后,他们有 在白板上创建了所有要求的 BST。最后,彼得 按优先顺序创建所有需求的列表。为此他 开始记下需求最右边的数量 BST(要求 6)。他继续最接近它的要求 (要求 8),然后是最接近此的下一个(要求 10), 等等。所有需求的最终优先顺序是 (从高到低)6、8、10、9、3、5、4、7、2、1。 现在可以使用优先需求来选择需求 在下一个版本中实现。

tets()
function tets() {
  var tasks = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"];

  //root
  var root = [tasks[0]];


  function prio(q, step) {

    //compare with step[0], now I just say 'random' more or less important for this demo;  
    var res = Math.random() > .5;

    if (res) {
      if (!step[2]) {
        step[2] = [q];

      } else {

        prio(q, step[2])
      }
    } else {

      if (!step[1]) {
        step[1] = [q]

      } else {
        prio(q, step[1])
      }
    }


  }



  for (var i = 1; i < tasks.length; i++) {
    prio(tasks[i], root)
  }
  console.log(root)
}
&lt;pre id="result"&gt; &lt;/pre&gt;

如您所见,数组的构建就像图像中的二叉树。每个元素都像 3 的数组一样构建:[0] = 名称,1 是左侧的节点,2 是右侧的节点。

主要问题是:

我怎样才能让 javascript 遍历这棵树并将最右边的元素作为最高优先级,将最左边的元素作为最低优先级?

【问题讨论】:

  • 这是一个简单的按顺序遍历你的树。

标签: javascript arrays algorithm


【解决方案1】:

基本上你可以使用Breadth-first search

执行顺序很重要,先寻找右孩子并遍历,显示节点信息,再迭代左孩子。

function traverse(a) {
    if (Array.isArray(a)) {
        a[2] && traverse(a[2]);
        a[0] && document.write(a[0] + '<br>');
        a[1] && traverse(a[1]);			
    }
}

var root = [5, [7, [2, [1]], [4]], [9, [3], [8, [10], [6]]]];
document.write('<pre>' + JSON.stringify(root, 0, 4) + '</pre>');
traverse(root);

【讨论】:

  • 结果不正确:6, 10, 8, 3, 9, 4, 1, 2, 7, 5 而不是 6, 8, 10, 9, 3, 5, 4, 7, 2, 1
  • 左侧比主要元素更优先(例如,在 OP 示例中,比 5 多 7 个)
  • 你看到随机元素,很难比较?
  • 我使用带有 OP 示例的静态列表测试了您的代码。所以不,不是随机的。
  • 就我对随机字符串进行的测试、在纸上绘制并检查您的结果而言,它是正确的。很感人,谢谢! ps 我不知道 && 技巧,使它更具可读性。 @Argon,6,8,10 是正确的结果吗?
【解决方案2】:

好的,所以我写了这个函数:

JavaScript

function getFlatArray(array, priority) {
  var result = [];
  getFlatArrayRecursive(array, priority, result);
  return result;
}

function getFlatArrayRecursive(array, priority, result) {
  for(var i = 0; i < priority.length; i++) {
    var currentItem = array[priority[i]];
    if(currentItem != null) {
      if(Array.isArray(currentItem)) {
        getFlatArrayRecursive(currentItem, priority, result);
      } 
      else {
        result.push(currentItem);
      }
    }
  }
}

var priority = [2, 0, 1];
var root = [
   5,
   [
      7,
      [
         2,
         [1]
      ],
      [4]
   ],
   [
      9,
      [3],
      [
         8,
         [10],
         [6]
      ]
   ]
];
var results = getFlatArray(root, priority);
console.log(results); //[6, 8, 10, 9, 3, 5, 4, 7, 2, 1]

JSFIDDLE

【讨论】:

    【解决方案3】:

    对树状态进行序列化,并在每个分支级别使用排序方法分析哪个分支更高/更低,直到遍历完整棵树。将最高/最低值存储在函数外部的全局变量中。即使当前分支级别不仅仅是二进制系统,这也应该有效。下面是递归函数内部代码在每个级别的示例:

    // example tasks at this branch level
    var tasks = [["a", 1, 2], ["b", 0, 1], ["c", 3, 0], ["d", 4, 1]];
    
    // make a copy so that original task list is maintained
    var tasksCopy = tasks;
    
    // sort the array from lowest left node to highest left node      
    var sortedLowToHigh = tasksCopy.sort(function(a, b) { 
         return a[1] - b[1];
    });
    
    // the lowest value will be at the first array element
    var highestPriorityTask = sortedLowToHigh[0][1];
    
    // sort the arry from highest right node to lowest right node
    var sortedHighToLow = tasksCopy.sort(function(a, b){
         return b[2] - a[2];
    });
    
    // the highest value will be at the first array element
    var lowestPriorityTask = sortedHighToLow[0][2];
    

    【讨论】:

      【解决方案4】:

      我认为就代码行而言,这个答案是最好的:

      function traverse(n) {
        return !Array.isArray(n) 
              ? (isNaN(n) ? [] : [n]) 
              : [...traverse(n[2]), ...traverse(n[0]), ...traverse(n[1]), ];
      }
      var root = [5, [7, [2, [1]], [4]], [9, [3], [8, [10], [6]]]];
      
      console.log(traverse(root));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-07
        • 1970-01-01
        • 2021-10-17
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        • 2017-09-07
        • 2017-10-18
        相关资源
        最近更新 更多