在JavaScript中删除图中的节点未完美工作。

huangapple go评论72阅读模式
英文:

Delete nodes in a Graph not working perfectly in js

问题

我已经创建了一个包含键和值对的图,键用于节点编号,值用于邻接边的值,这是一个包含相邻边的数组。在这里,我编写了一个函数,该函数将删除图中的节点和邻接边,但在这里该函数不起作用,我应该在这里修改什么以便得到像这样的图 {1:[2,4],2:[1,3],3:[1,4]},以下是给定的代码:

var graph = {
  1: [2, 4],
  2: [1, 3],
  3: [2, 4],
  4: [1, 4]
};

function deleteNode(key){
  if(!graph[key]){
    return;
  }else{
    graph[key].splice(key, 1);
  }
}

deleteNode(3)
console.log(graph);

在代码中,应该修改的部分是 graph[key].splice(key, 1);,你应该将其改为 graph[key] = [],以删除节点及其邻接边。修改后的代码如下:

var graph = {
  1: [2, 4],
  2: [1, 3],
  3: [2, 4],
  4: [1, 4]
};

function deleteNode(key){
  if(!graph[key]){
    return;
  }else{
    delete graph[key];
    for (var otherKey in graph) {
      var index = graph[otherKey].indexOf(key);
      if (index !== -1) {
        graph[otherKey].splice(index, 1);
      }
    }
  }
}

deleteNode(3)
console.log(graph);

这将删除节点3以及相关的邻接边,得到你期望的图结构。

英文:

I have created a graph which containing key and value pair ,key is for node number and value for adjacency list value which is an array of adjacent edges, here I wrote a function that will delete the node and adjacency edges in the graph, but here the function is not working ,which thing should I have to modified here that I want graph like {1:[2,4],2:[1,3],3:[1,4]} code is given below

var graph = {
    1: [2, 4],
    2: [1, 3],
    3: [2, 4],
    4: [1, 4]
  };
function deleteNode(key){
    if(!graph[key]){
      return;
    }else{
      graph[key].splice(key, 1);
    }
  }
  deleteNode(3)
  console.log(graph);

答案1

得分: 1

如果要删除节点3,则结果中不应再提到3。对于示例图,预期结果应为:

{
    1: [2, 4],
    2: [1],
    4: [1, 4]
}

因此,在您的代码中,首先必须迭代节点的所有邻居,并从它们的邻接列表中删除节点。然后删除节点本身:

function deleteNode(key) {
    if (!graph[key]) return;
    // 删除连接到该节点的任何边
    for (const neighbor of graph[key]) {
        graph[neighbor] = graph[neighbor].filter(target => target != key);
    }
    // 删除节点本身
    delete graph[key];
}

const graph = {
    1: [2, 4],
    2: [1, 3],
    3: [2, 4],
    4: [1, 4]
};
deleteNode(3);
console.log(graph);
英文:

If you want to remove node 3, the result should not have any mention of 3 in it anymore. For the example graph the expected result should be:

{
    1: [2, 4],
    2: [1],
    4: [1, 4],
}

So in your code you would have to first iterate all the neighbors of the node, and remove the node from their adjacency lists. And then delete the node itself:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function deleteNode(key){
    if (!graph[key]) return;
    // Remove any edge that connects to this node
    for (const neighbor of graph[key]) {
        graph[neighbor] = graph[neighbor].filter(target =&gt; target != key);
    }
    // Remove the node itself
    delete graph[key];
}

const graph = {
    1: [2, 4],
    2: [1, 3],
    3: [2, 4],
    4: [1, 4]
};
deleteNode(3)
console.log(graph);

<!-- end snippet -->

答案2

得分: 1

不要尝试在原地移动键,最好构建一个新对象,删除不需要的键。

还有一些建议:

  • 记住,你的键实际上是字符串,即使你没有打算这样;所以你必须删除 "3" 而不是 3

  • 不要改变全局变量,最好让你的函数接收一个图形值并返回一个新值。

  • 你的预期结果目前还不太明确 - 你可能计划“单独”修改列表以“重命名”已移动的值,并删除已删除的值?

  • 当你这样做时,你会意识到将键作为字符串而列表条目作为数字是多么烦人。也许你应该考虑切换到不同的设计,使用数组的数组,即始终从0开始?

var graph = {
  1: [2, 4],
  2: [1, 3],
  3: [2, 4],
  4: [1, 4]
};

function deleteNode(graph, keyToDelete) {
  const oldKeys = Object.keys(graph);
  const listsToKeep = Object.entries(graph).filter(([key, list]) => key !== keyToDelete).map(([key, list]) => list);
  const newLen = Object.values(listsToKeep).length;
  const newKeys = oldKeys.slice(0, newLen);

  return Object.fromEntries(
    newKeys.map(
      (key, i) => [key, listsToKeep[i]]
    )
  );
}

graph = deleteNode(graph, "3");
console.log(graph);

希望这有所帮助。

英文:

Don't try to shift the keys in situ

It is better to build a new object, with the unwanted key removed.

A few other pointers:

  • Remember that your keys are in fact strings, even if you did not intend that; so you must delete "3" not 3

  • Rather than mutating a global variable it is clearer for your function to receive a value of graph and return a new value.

  • Your expected result does not make much sense yet - presumably you are planning to separately amend the lists to "rename" the values that have moved, and delete the one that has been deleted?

  • When you do that you will realise how annoying it is to have keys as strings and yet list entries as numbers. Maybe you should switch to a different design, that uses arrays of arrays, i.e. always starting at 0?

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

var graph = {
  1: [2, 4],
  2: [1, 3],
  3: [2, 4],
  4: [1, 4]
};

function deleteNode(graph, keyToDelete) {
  const oldKeys = Object.keys(graph)
  const listsToKeep = Object.entries(graph).filter(([key, list]) =&gt; key !== keyToDelete).map(([key, list]) =&gt; list)
  const newLen = Object.values(listsToKeep).length
  const newKeys = oldKeys.slice(0, newLen)

  return Object.fromEntries(
    newKeys.map(
      (key, i) =&gt; [key, listsToKeep[i]]
    )
  )

}
graph = deleteNode(graph, &quot;3&quot;)
console.log(graph);

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月12日 17:05:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712059.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定