From aa48432371e69091a012bd7f60237ca1af642f72 Mon Sep 17 00:00:00 2001 From: DavidCai Date: Sun, 1 Jan 2017 14:24:01 +0800 Subject: [PATCH] implement basic undirected graph --- .travis.yml | 5 ++-- Makefile | 5 ++-- graph/graph.go | 66 +++++++++++++++++++++++++++++++++++++++++++++ graph/graph_test.go | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 graph/graph.go create mode 100644 graph/graph_test.go diff --git a/.travis.yml b/.travis.yml index 0f46aa8..7a15156 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,8 @@ script: - go test -v -race -coverprofile=mh.coverprofile ./min-heap - go test -v -race -coverprofile=avl.coverprofile ./avl-tree - go test -v -race -coverprofile=pat.coverprofile ./pat-tree - - go test -v -race -coverprofile=pat.coverprofile ./sort - - go test -v -race -coverprofile=pat.coverprofile ./search + - go test -v -race -coverprofile=sort.coverprofile ./sort + - go test -v -race -coverprofile=search.coverprofile ./search + - go test -v -race -coverprofile=graph.coverprofile ./graph - gover - goveralls -coverprofile=gover.coverprofile -service=travis-ci \ No newline at end of file diff --git a/Makefile b/Makefile index b9e2e52..2e73f46 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,9 @@ cover: go test -v -race -coverprofile=bt.coverprofile ./b-tree go test -v -race -coverprofile=avl.coverprofile ./avl-tree go test -v -race -coverprofile=pat.coverprofile ./pat-tree - go test -v -race -coverprofile=pat.coverprofile ./sort - go test -v -race -coverprofile=pat.coverprofile ./search + go test -v -race -coverprofile=sort.coverprofile ./sort + go test -v -race -coverprofile=search.coverprofile ./search + go test -v -race -coverprofile=graph.coverprofile ./graph gover go tool cover -html=gover.coverprofile rm -rf *.coverprofile diff --git a/graph/graph.go b/graph/graph.go new file mode 100644 index 0000000..61f78b7 --- /dev/null +++ b/graph/graph.go @@ -0,0 +1,66 @@ +package graph + +import ( + "fmt" +) + +const errInvaliVertexNumber = "graph: invalid vertex number %v" + +// Graph represents an undirected graph. +type Graph struct { + bags [][]int + edges int +} + +// New returns a new undirected graph instance with v vertexs. +func New(v int) *Graph { + return &Graph{bags: make([][]int, v)} +} + +// Vertexs returns the number of vertexs of the graph. +func (g Graph) Vertexs() int { + return len(g.bags) +} + +// Edges returns the number of edges of the graph. +func (g Graph) Edges() int { + return g.edges +} + +// addEdge adds an edge to the graph. +func (g *Graph) addEdge(v, w int) { + if v < 0 || v >= len(g.bags) { + panic(fmt.Errorf(errInvaliVertexNumber, v)) + } + + if w < 0 || w >= len(g.bags) { + panic(fmt.Errorf(errInvaliVertexNumber, w)) + } + + for _, b := range g.bags[v] { + if b == w { + panic(fmt.Errorf(errInvaliVertexNumber, w)) + } + } + + g.bags[v] = append(g.bags[v], w) + + for _, b := range g.bags[w] { + if b == v { + panic(fmt.Errorf(errInvaliVertexNumber, v)) + } + } + + g.bags[w] = append(g.bags[w], v) + + g.edges++ +} + +// GetAdjacentVertexs returns all adjacent vertexs of v in the graph. +func (g *Graph) GetAdjacentVertexs(v int) []int { + if v < 0 || v >= len(g.bags) { + panic(fmt.Errorf(errInvaliVertexNumber, v)) + } + + return g.bags[v] +} diff --git a/graph/graph_test.go b/graph/graph_test.go new file mode 100644 index 0000000..d79dd4b --- /dev/null +++ b/graph/graph_test.go @@ -0,0 +1,47 @@ +package graph + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +type GraphSuite struct { + suite.Suite + + g *Graph +} + +func (s *GraphSuite) SetupTest() { + s.g = New(10) +} + +func (s GraphSuite) TestNew() { + s.Equal(10, len(s.g.bags)) +} + +func (s GraphSuite) TestVertexs() { + s.Equal(10, s.g.Vertexs()) +} + +func (s GraphSuite) TestEdges() { + s.Equal(0, s.g.Edges()) + s.g.addEdge(0, 1) + s.Equal(1, s.g.Edges()) +} + +func (s GraphSuite) TestEdgesFailed() { + s.Panics(func() { s.g.addEdge(11, 1) }) + s.Panics(func() { s.g.addEdge(1, 11) }) +} + +func (s GraphSuite) TestGetAdjacentVertexs() { + s.g.addEdge(0, 1) + s.g.addEdge(0, 2) + + s.Equal([]int{1, 2}, s.g.GetAdjacentVertexs(0)) +} + +func TestGraph(t *testing.T) { + suite.Run(t, new(GraphSuite)) +}