2012-10-04 80 views
9

Tôi đang cố gắng xây dựng một đồ thị theo danh sách kề, nghĩa là tôi cần một danh sách cho tất cả các nút, và bên trong mọi nút nút, tôi cũng cần cấu trúc dữ liệu để giữ tất cả các nút liền kề. Chỉ cần tự hỏi cấu trúc tốt nhất sẽ làm gì (tìm kiếm nhanh cho lớp nút đích). Một mảng có hoạt động không?Danh sách kề và đồ thị

+2

Các ngôn ngữ Ruby được biết đến với việc sử dụng nặng nề của băm và mảng cho hầu hết các trường hợp thay vì cấu trúc dữ liệu chuyên ngành. Ruby ưu tiên năng suất lập trình, do đó, các mảng và mảng có khả năng phong phú để các nhà phát triển sử dụng chúng mọi lúc. Trong trường hợp của bạn, tôi nghĩ rằng mảng sẽ là tốt. – Valentin

+1

Trong một ngôn ngữ OOP như Ruby, hãy xem xét biểu diễn mỗi nút trong biểu đồ dưới dạng đối tượng duy trì các cạnh của nó làm tham chiếu đến các đối tượng khác cùng loại. –

Trả lời

23

Đây là một cách để xây dựng biểu đồ được hướng dẫn trong Ruby, trong đó mỗi nút duy trì tham chiếu đến người kế thừa của nó, nhưng các nút có thể được tham chiếu theo tên. Trước tiên, chúng tôi cần lớp học cho các nút:

class Node 

    attr_reader :name 

    def initialize(name) 
    @name = name 
    @successors = [] 
    end 

    def add_edge(successor) 
    @successors << successor 
    end 

    def to_s 
    "#{@name} -> [#{@successors.map(&:name).join(' ')}]" 
    end 

end 

Mỗi nút duy trì tham chiếu đến người kế nhiệm. Không biết bạn cần loại hoạt động nào, tôi chưa xác định bất kỳ thao tác nào thực sự thực hiện truyền tải đồ thị, nhưng mỗi nút có tham chiếu đến người kế thừa của nó khiến việc duyệt qua biểu đồ tầm thường.

Bây giờ chúng ta sẽ tạo một lớp học để đại diện cho toàn bộ đồ thị:

class Graph 

    def initialize 
    @nodes = {} 
    end 

    def add_node(node) 
    @nodes[node.name] = node 
    end 

    def add_edge(predecessor_name, successor_name) 
    @nodes[predecessor_name].add_edge(@nodes[successor_name]) 
    end 

    def [](name) 
    @nodes[name] 
    end 

end 

Lớp này giữ một hash của các nút của nó, keyed theo tên. Điều này làm cho việc thu hồi một nút cụ thể dễ dàng.

Dưới đây là một ví dụ về một đồ thị có chứa một chu kỳ:

graph = Graph.new 
graph.add_node(Node.new(:a)) 
graph.add_node(Node.new(:b)) 
graph.add_node(Node.new(:c)) 
graph.add_edge(:a, :b) 
graph.add_edge(:b, :c) 
graph.add_edge(:c, :a) 
puts graph[:a] #=> a -> [b] 
puts graph[:b] #=> b -> [c] 
puts graph[:c] #=> c -> [a] 
Các vấn đề liên quan