我定义了一个具有以下结构的图表 “(()()...) 外部列表是图形本身,它包含节点和边缘。 第一个内部列表是所有节点的列表。 以下列表是边缘。边缘由成对的节点组成。 所以这是一个包含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")))
在我检查了第一个节点是否包含在边缘列表中之后,我不确定下一步是什么。我知道如果它被包含,我需要通过并删除包含它的列表。然后我需要转到节点列表中的下一个节点并检查......但我不知道该怎么做。
非常感谢任何帮助!
答案 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))