变量在while循环外丢失值-Javascript

时间:2018-08-12 07:05:23

标签: javascript algorithm loops while-loop linked-list

我正在尝试解决涉及链表的问题。对链接列表进行分区,以使小于分区的值排在最前面,然后是等于或大于分区的值。

示例:

input: 90 -> 30 -> 40 -> 50 -> 100 -> 40
partition: 50
output: 30 -> 40 -> 40 -> 50 -> 100 -> 90

所有小于分区(50)的节点都比所有大于分区(50)的节点先出现。

function partitionLl(node) {
  let list = {
    "head": {
      "data": 90,
      "next": {
        "data": 30,
        "next": {
          "data": 40,
          "next": {
            "data": 50,
            "next": {
              "data": 100,
              "next": {
                "data": 40,
                "next": {
                  "data": 15,
                  "next": {
                    "data": 90,
                    "next": {
                      "data": 200,
                      "next": {
                        "data": 90,
                        "next": {
                          "data": 10,
                          "next": {
                            "data": 90,
                            "next": null
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  let test;
  let current = list.head;
  let p1 = {
    data: null,
    next: null
  };
  let p2 = current;

  while (current !== null) {
    if (current.data < node) {
      p1 = current;
      p1 = p1.next;
    } else {
      p2 = current;
      p2 = p2.next;
    }

    current = current.next;
  }
  console.log(p1)
  console.log(p2)

}

partitionLl(50)

这是我拥有的代码,我想要获得的列表在循环中很棒,它具有我需要的列表。问题是我需要在循环完成时附加这些列表(p1和p2),但是当在while循环之外时,变量记录的内容完全不同且不准确。

在循环的内部和外部都跟踪当前变量。不知道为什么会这样,或者不确定哪种作用域循环会导致这种情况。我将如何在循环外访问这些值?

3 个答案:

答案 0 :(得分:1)

OPs程序的问题在于它从不实际更改列表,也没有为结果建立新列表,即,从未发生对数据或下一个属性的分配。仅移动“指针” p1和p2,直到到达列表的末尾。 p1或p2的分配方式最终都将为空。

一种解决方案将创建当前元素的副本,并通过设置下一个属性将其附加到p1或p2。

像这样:

function partitionLl(node) {
  let list = {
    "head": {
      "data": 90,
      "next": {
        "data": 30,
        "next": {
          "data": 40,
          "next": {
            "data": 50,
            "next": {
              "data": 100,
              "next": {
                "data": 40,
                "next": {
                  "data": 15,
                  "next": {
                    "data": 90,
                    "next": {
                      "data": 200,
                      "next": {
                        "data": 90,
                        "next": {
                          "data": 10,
                          "next": {
                            "data": 90,
                            "next": null
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

    let p1 = {
        "head": null
    }
    let t1 = p1.head
    let p2 = {
        "head": null
    }
    let t2 = p2.head
    let current = list.head
    while (current !== null) {
      if (current.data < node) {

          if(p1.head === null) {
              p1.head = {
                  "data": current.data,
                  "next": null
              }
              t1 = p1.head
          } else {
              t1.next = {
                  "data": current.data,
                  "next": null
              }
              t1 = t1.next
          }
    } else {
          if(p2.head === null) {
              p2.head = {
                  "data": current.data,
                  "next": null
              }
              t2 = p2.head
          } else {
              t2.next = {
                  "data": current.data,
                  "next": null
              }
              t2 = t2.next
          }
    }

    current = current.next;
  }
  console.log(p1)
  console.log(p2)

}

partitionLl(50)

答案 1 :(得分:0)

通常使用链接列表是使用递归的练习。

我将构建一些用于处理链表的原语,然后将它们组合以产生所需的结果-partition可以从filterconcat来构建:

// given a list return a new list that contains only those items than pass the test function const filter = (list, test) => { const next = list.next ? filter(list.next, test) : null; if (test(list.data)) { return { data: list.data, next }; } return next; };

// given two lists return a new list with them concatenated together const concat = (l1, l2) => { if (!l1.next) { return { data: l1.data, next: l2 }; } return { data: l1.data, next: concat(l1.next, l2) }; };

const partition = (list, value) => { const smaller = filter(list, d => d < value); const bigger = filter(list, d => d >= value); return concat(smaller, bigger); };

答案 2 :(得分:0)

对于较小的值,您可以采用三个列表:(a)left; (b)大于或等于right; (c)将right部分分为firstlast,其中所有值进入last列表,直到找到枢轴值,然后所有值进入first

最后,将所有列表合并为一个列表,然后返回一个新列表。

function partition(list, pivot) {
    var leftHead = {},
        left = leftHead,
        firstHead = {},
        lastHead = {},
        right = lastHead,
        isLast = true,
        node = list.head;

    while (node) {
        if (node.data === pivot && isLast) {
            right = firstHead;
            isLast = false;
        }

        if (node.data < pivot) {
            left.next = { data: node.data };
            left = left.next;
        } else {
            right.next = { data: node.data };
            right = right.next;
        }
        node = node.next;
    }

    if (firstHead.next) {
        right.next = lastHead.next;
        left.next = firstHead.next;
    } else {
        left.next = lastHead.next;
    }
    return { head: leftHead.next };

}

var list1 = { head: { data: 90, next: { data: 30, next: { data: 40, next: { data: 50, next: { data: 100, next: { data: 40, next: { data: 15, next: { data: 90, next: { data: 200, next: { data: 90, next: { data: 10, next: { data: 90, next: null } } } } } } } } } } } } },
    list2 = { head: { data: 90, next: { data: 30, next: { data: 40, next: { data: 50, next: { data: 100, next: { data: 40 } } } } } } };

console.log(partition(list1, 50));
console.log(partition(list2, 50));
.as-console-wrapper { max-height: 100% !important; top: 0; }