tree

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2022 License: Apache-2.0 Imports: 7 Imported by: 1

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type E added in v0.4.0

type E[T any] struct {
	types.Types
	Root *Node[T] `json:",omitempty"`
}

E ("tree-e") is an encapsulating struct to contain the Root Node and all possible Types for any Node. Most users of a tree will make direct use of E.Root (which can safely be swapped out for a root Node reference at any time). Tree implements the rwxrob/json/AsJSON interface and uses custom methods for MarshalJSON and UnmarshalJSON to facilitate storage, transfer, and documentation.

func New

func New[T any](types []string) *E[T]

New creates a new tree initialized with the given types and returns.

func (*E[T]) Init added in v0.4.0

func (t *E[T]) Init(types []string) *E[T]

Init initializes a tree creating its Root Node reference and assigning it the type of 1 (0 is reserved for UNKNOWN). Init then assigns its Types and indexes the TypesMap.

func (*E[T]) JSON added in v0.4.0

func (s *E[T]) JSON() ([]byte, error)

JSONL implements rwxrob/json.AsJSON.

func (*E[T]) JSONL added in v0.4.0

func (s *E[T]) JSONL() ([]byte, error)

JSONL implements rwxrob/json.AsJSON.

func (E[T]) Log added in v0.4.0

func (s E[T]) Log()

Log implements rwxrob/json.Logger.

func (E[T]) LogLong added in v0.4.0

func (s E[T]) LogLong()

LogLong implements rwxrob/json.Logger.

func (*E[T]) Node added in v0.4.0

func (t *E[T]) Node(typ ...any) *Node[T]

Node returns new detached Node initialized for this same tree. Either an integer or string type may be passed and if none are passed the UNKNOWN (0) type will be assigned.

func (*E[T]) Print added in v0.4.0

func (s *E[T]) Print()

String implements rwxrob/json.Printer.

func (*E[T]) PrintLong added in v0.4.0

func (s *E[T]) PrintLong()

PrintLong implements rwxrob/json.Printer.

func (E[T]) String added in v0.4.0

func (s E[T]) String() string

String implements rwxrob/json.Stringer and fmt.Stringer.

func (E[T]) StringLong added in v0.4.0

func (s E[T]) StringLong() string

StringLong implements rwxrob/json.Stringer.

type Node

type Node[T any] struct {
	T     int      `json:"T"`          // type
	V     T        `json:",omitempty"` // value
	P     *Node[T] `json:"-"`          // up/parent
	Count int      `json:"-"`          // node count
	Tree  *E[T]    `json:"-"`          // optional tree with type names
	// contains filtered or unexported fields
}

Node is an implementation of a "node" from traditional data structures. Nodes can have other nodes under then (which some call being a "parent" (P)). Nodes can also have a value (V). All nodes have a specific integer type (T) (which most will map to constants and slices of strings containing their readable name equivalent). The terms "up", "down", "under", "left", and "right" are consistent with the common visualization of a tree, but are not necessarily constraints on implementation or visual representation. Node is implemented as a linked list for maximum performance. Also see tree.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
	"github.com/rwxrob/structs/types"
)

func main() {

	// flexible
	n := new(tree.Node[any])
	n.Print()

	// specific
	m := new(tree.Node[int])
	m.Print()

	// default type: UNKNOWN == 0
	fmt.Println(n.T == types.UNKNOWN, m.T == types.UNKNOWN)

	// values matching zero value are omitted

}
Output:

{"T":0}
{"T":0}
true true
Example (Properties)
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {

	// Nodes have these properties updating every time
	// their state is changed so that queries need not
	// to the checks again later.

	// initial state
	n := new(tree.Node[any])
	fmt.Println("n:", n.P == nil, n.V, n.Count)
	u := n.Add(1, nil)
	fmt.Println("n:", n.P == nil, n.V, n.Count)
	fmt.Println("u:", u.P == nil, u.V, u.Count)

	// make an edge node
	u.V = "something"

	// break edge by forcing it to have nodes and a value (discouraged)
	u.Add(9001, "muhaha")
	fmt.Println("u:", u.P == nil, u.V, u.Count)

}
Output:

n: true <nil> 0
n: true <nil> 1
u: false <nil> 0
u: false something 1
Example (Type_is_Integer)
package main

import (
	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	n.T = 1
	n.Print()
	//n.T = "one" // BOOM!

}
Output:

{"T":1}
Example (Value_Depends_on_Instantiation)
package main

import (
	"github.com/rwxrob/structs/tree"
)

func main() {

	z := new(tree.Node[any])
	z.Print() // values that are equiv of zero value for type are omitted

	// flexible
	n := new(tree.Node[any])
	n.V = 1
	n.Print()
	n.V = true
	n.Print()
	n.V = "foo"
	n.Print()

	// strict
	m := new(tree.Node[int])
	m.V = 1
	m.Print()
	//m.V = true // BOOM!

}
Output:

{"T":0}
{"T":0,"V":1}
{"T":0,"V":true}
{"T":0,"V":"foo"}
{"T":0,"V":1}

func (*Node[T]) Add

func (n *Node[T]) Add(t int, v T) *Node[T]

Add creates a new Node with type and value under and returns. It also updates Count.

func (*Node[T]) Append

func (n *Node[T]) Append(u *Node[T])

Append adds an existing Node under this one as if Add had been called.

func (*Node[T]) Cut

func (n *Node[T]) Cut() *Node[T]

Cut removes a Node from under the one above it and returns.

Example (First)
package main

import (
	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	c := n.Add(1, nil)
	n.Add(2, nil)
	n.Add(3, nil)
	n.Print()
	x := c.Cut()
	n.Print()
	x.Print()
}
Output:

{"T":0,"N":[{"T":1},{"T":2},{"T":3}]}
{"T":0,"N":[{"T":2},{"T":3}]}
{"T":1}
Example (Last)
package main

import (
	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	n.Add(1, nil)
	n.Add(2, nil)
	c := n.Add(3, nil)
	n.Print()
	x := c.Cut()
	n.Print()
	x.Print()
}
Output:

{"T":0,"N":[{"T":1},{"T":2},{"T":3}]}
{"T":0,"N":[{"T":1},{"T":2}]}
{"T":3}
Example (Middle)
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	n.Add(1, nil)
	c := n.Add(2, nil)
	n.Add(3, nil)
	n.Print()
	fmt.Println(n.Count)
	x := c.Cut()
	n.Print()
	fmt.Println(n.Count)
	x.Print()
}
Output:

{"T":0,"N":[{"T":1},{"T":2},{"T":3}]}
3
{"T":0,"N":[{"T":1},{"T":3}]}
2
{"T":2}

func (*Node[T]) Init

func (n *Node[T]) Init()

Init resets the node to its empty/zero state as if just created for the first time.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {

	// create and print a brand new one
	n := new(tree.Node[any])
	n.Print()

	// add something to it
	n.V = "something"
	n.Print()

	// initialize it back to "empty"
	n.Init()
	n.Print()

	// now try with something with a tricker zero value
	n.V = func() {}
	// log.Println(n.V) // "0x5019e0" yep it's there
	// n.Print()     // would log error and fail to marshal JSON

	// check it's properties
	fmt.Println(n.P != nil, n.Count)

}
Output:

{"T":0}
{"T":0,"V":"something"}
{"T":0}
false 0

func (*Node[T]) JSON

func (s *Node[T]) JSON() string

JSON implements rwxrob/json.Printer.

func (*Node[T]) JSONL

func (s *Node[T]) JSONL() string

JSONL implements rwxrob/json.Printer.

func (Node[T]) Log

func (s Node[T]) Log()

Log implements rwxrob/json.Printer.

func (Node[T]) LogL

func (s Node[T]) LogL()

PLog implements rwxrob/json.Printer.

func (Node[T]) MarshalJSON

func (s Node[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements encoding/json.Marshaler and it needed to fulfill the list of nodes since they are internally stored as a linked list.

func (*Node[T]) Morph

func (n *Node[T]) Morph(c *Node[T])

Morph initializes the node with Init and then sets it's value (V) and type (T) and all of its attachment references to those of the Node passed thereby preserving the Node reference of this method's receiver.

Example
package main

import (
	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	n.Add(2, "some")
	m := new(tree.Node[any])
	m.Morph(n)
	n.Print()
	m.Print()
}
Output:

{"T":0,"N":[{"T":2,"V":"some"}]}
{"T":0,"N":[{"T":2,"V":"some"}]}

func (*Node[T]) Nodes

func (n *Node[T]) Nodes() []*Node[T]

Nodes returns all the nodes under this Node. Prefer checking Count when the values are not needed.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {

	// create the first tree
	n := new(tree.Node[any])
	n.Add(1, nil)
	n.Add(2, nil)
	fmt.Println(n.Nodes(), n.Count)

	// and another added under it
	m := n.Add(3, nil)
	m.Add(3, nil)
	m.Add(3, nil)
	fmt.Println(m.Nodes(), m.Count)

}
Output:

[{"T":1} {"T":2}] 2
[{"T":3} {"T":3}] 2

func (*Node[T]) PPrint

func (s *Node[T]) PPrint()

PPrint implements rwxrob/json.Printer.

func (*Node[T]) Print

func (s *Node[T]) Print()

Print implements rwxrob/json.Printer.

func (Node[T]) String

func (s Node[T]) String() string

String implements rwxrob/json.Printer and fmt.Stringer.

func (*Node[T]) Take

func (n *Node[T]) Take(from *Node[T])

Take moves all nodes from another under itself.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {

	// build up the first
	n := new(tree.Node[any])
	n.T = 10
	n.Add(1, nil)
	n.Add(2, nil)
	n.Add(3, nil)
	n.Print()
	fmt.Println(n.Count)

	// now take them over

	m := new(tree.Node[any])
	m.T = 20
	m.Print()
	fmt.Println(m.Count)
	m.Take(n)
	m.Print()
	fmt.Println(m.Count)
	n.Print()
	fmt.Println(n.Count)

}
Output:

{"T":10,"N":[{"T":1},{"T":2},{"T":3}]}
3
{"T":20}
0
{"T":20,"N":[{"T":1},{"T":2},{"T":3}]}
3
{"T":10}
0

func (*Node[T]) WalkDeepPre

func (n *Node[T]) WalkDeepPre(do func(n *Node[T]))

WalkDeepPre will pass each Node in the tree to the given function traversing in a synchronous, depth-first, preorder way. The function passed may be a closure containing variables, contexts, or a channel outside of its own scope to be updated for each visit. This method uses functional recursion which may have some limitations depending on the depth of node trees required.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	n.Add(1, nil).Add(11, nil)
	n.Add(2, nil).Add(22, nil)
	n.Add(3, nil).Add(33, nil)
	n.WalkDeepPre(func(c *tree.Node[any]) { fmt.Print(c.T, " ") })
}
Output:

0 1 11 2 22 3 33

func (*Node[T]) WalkLevels

func (n *Node[T]) WalkLevels(do func(n *Node[T]))

WalkLevels will pass each Node in the tree to the given function traversing in a synchronous, breadth-first, leveler way. The function passed may be a closure containing variables, contexts, or a channel outside of its own scope to be updated for each visit. This method uses functional recursion which may have some limitations depending on the depth of node trees required.

Example
package main

import (
	"fmt"

	"github.com/rwxrob/structs/tree"
)

func main() {
	n := new(tree.Node[any])
	n.Add(1, nil).Add(11, nil)
	n.Add(2, nil).Add(22, nil)
	n.Add(3, nil).Add(33, nil)
	n.WalkLevels(func(c *tree.Node[any]) { fmt.Print(c.T, " ") })
}
Output:

0 1 2 3 11 22 33

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL