如何从方案中的图表中删除节点?

时间:2014-11-19 23:22:36

标签: graph scheme racket

我定义了一个具有以下结构的图表 “(()()...) 外部列表是图形本身,它包含节点和边缘。 第一个内部列表是所有节点的列表。 以下列表是边缘。边缘由成对的节点组成。 所以这是一个包含3个节点和2个边的示例图: ((n1 n2 n3)(n1 n2)(n1 n3))

我能够删除这样的边缘:

(define (delete-edge edge)
    (if (member edge (edges))
        (build-graph (nodes) (remove edge (edges)))
        "ERROR no edge to remove"))

这是构建图

(define (build-graph nodes edges)
    (set! graph (append (list nodes) edges)))

但是我在删除节点时遇到了麻烦。如果我删除一个节点,我还必须删除与它相关的所有边。到目前为止我所拥有的是:

(define (delete-node node)
    (cond ((member (car (car graph)) (cdr graph))
           ("not implemented yet"))
        ("No Node to delete")))

在我检查了第一个节点是否包含在边缘列表中之后,我不确定下一步是什么。我知道如果它被包含,我需要通过并删除包含它的列表。然后我需要转到节点列表中的下一个节点并检查......但我不知道该怎么做。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:3)

在Scheme中,您应该更喜欢函数式编程风格的解决方案。换句话说:改变全局变量(在这种情况下为graph)不是一个好主意,最好将图形作为参数接收并返回带有结果的新修改图形。例如,这解决了您的问题:

(define (delete-node node graph)
  (cons (remove node (car graph))                  ; remove node from list of nodes
        (filter (lambda (e) (not (member node e))) ; delete edges that contain the node
                (cdr graph))))

以上使用list helper函数来实现解决方案,这是编写程序的惯用方法。请注意,如果我们尝试删除不存在的节点,则将返回相同的输入图,不进行修改。像这样使用它:

(define graph '((n1 n2 n3) (n1 n2) (n1 n3)))

(delete-node 'n2 graph)
=> '((n1 n3) (n1 n3))
(delete-node 'n5 graph)
=> '((n1 n2 n3) (n1 n2) (n1 n3))

如果您确实需要修改graph全局变量,请在之后执行:

(set! graph (delete-node 'n2 graph))