pull/154/merge
Esmaeil Pahang 2 years ago committed by GitHub
commit a899e9667b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -29,6 +29,7 @@ Implementation of various data structures and algorithms in Go.
- [AVLTree](#avltree)
- [BTree](#btree)
- [BinaryHeap](#binaryheap)
- [SplayTree](#spalytree)
- [Functions](#functions)
- [Comparator](#comparator)
- [Iterator](#iterator)
@ -846,6 +847,100 @@ func main() {
}
```
#### SplayTree
<b>A polymorphic splay tree implementation in Go(lang)</b>
splay is defined around the <code>SplayTree</code> interface:
type SplayTree interface {
SetRoot(n *Node)
GetRoot() *Node
Ord(key1, key2 interface{}) int
}
Your <code>SplayTree</code> implementation must contain a <code>root *Node</code> where
type Node struct {
key interface{}
value interface{}
parent *Node
left *Node
right *Node
}
<code>SetRoot</code> and <code>GetRoot</code> are the getter and setter for root, and <code>Ord</code> is a method for
comparing keys must return 0 if key1 < key2, 1 if key1 == key2, or 2 if
key1 > key2 (for whatever definitions of <, ==, and > apply to your key type).
Here's an example assuming we have the splay directory in the same directory as
our project (a very similar example is given in <i>example.go</i>):
package main
import (
"./splay"
"fmt"
"unicode/utf8"
)
type Tree struct {
root *splay.Node
}
func (T *Tree) SetRoot(n *splay.Node) {
T.root = n
}
func (T *Tree) GetRoot() *splay.Node {
return T.root
}
// This Splay Tree will use strings as keys and strings as values
// It returns 0, 1, or 2 based on the lexical comparison of the key strings
func (T *Tree) Ord(key1, key2 interface{}) int {
for i := 0; i < len(key1.(string)); {
c1, j := utf8.DecodeRuneInString(key1.(string)[i:])
c2, _ := utf8.DecodeRuneInString(key2.(string)[i:])
if c1 < c2 {
return 0
} else if c1 > c2 {
return 2
}
i += j
}
if len(key1.(string)) < len(key2.(string)) {
return 0
} else if len(key1.(string)) == len(key2.(string)) {
return 1
} else {
return 2
}
}
func main() {
T := new(Tree)
splay.Insert(T, "hello", "world")
splay.Insert(T, "foo", "bar")
splay.Insert(T, "what's your name", "buddy?")
splay.Insert(T, "Goku says", "Kamehameha")
err := splay.Insert(T, "foo", "foo")
fmt.Println(err)
v := splay.Find(T, "Goku says")
fmt.Println(v)
splay.Print(T)
splay.Delete(T, "foo")
err = splay.Delete(T, "foo")
fmt.Println(err)
splay.Print(T)
}
## Functions
Various helper functions used throughout the library.

@ -0,0 +1,377 @@
package splay
import (
"errors"
"fmt"
"strings"
)
type Node struct {
key interface{}
value interface{}
parent *Node
left *Node
right *Node
}
type SplayTree interface {
SetRoot(n *Node)
GetRoot() *Node
Ord(key1, key2 interface{}) int // 0 => LESS, 1 => EQUAL, 2 => GREATER
}
func Search(ST SplayTree, key interface{}) *Node {
return SearchNode(ST, key, ST.GetRoot())
}
func SearchNode(ST SplayTree, key interface{}, n *Node) *Node {
if n == nil {
return nil
} else {
switch ST.Ord(key, n.key) {
case 0:
return SearchNode(ST, key, n.left)
case 1:
return n
case 2:
return SearchNode(ST, key, n.right)
}
return nil
}
}
func Find(ST SplayTree, key interface{}) interface{} {
return FindNode(ST, key, ST.GetRoot()) // // Returns value associated with key if it exists, or nil if not
}
func FindNode(ST SplayTree, key interface{}, n *Node) interface{} {
if n == nil {
return nil
} else {
switch ST.Ord(key, n.key) {
case 0:
return FindNode(ST, key, n.left)
case 1:
return n.value
case 2:
return FindNode(ST, key, n.right)
}
return nil
}
}
func Insert(ST SplayTree, key, value interface{}) error {
if Search(ST, key) != nil {
s := fmt.Sprintf("splay.Insert Error: key %v already exists", key)
return errors.New(s)
}
n := InsertNode(ST, key, value, ST.GetRoot())
Splay(ST, n)
return nil
}
func InsertNode(ST SplayTree, key interface{}, value interface{}, n *Node) *Node {
if n == nil {
_n := new(Node)
_n.key = key
_n.value = value
ST.SetRoot(_n)
return ST.GetRoot()
}
switch ST.Ord(key, n.key) {
case 0:
if n.left == nil {
n.left = new(Node)
n.left.key = key
n.left.value = value
n.left.parent = n
return n.left
} else {
return InsertNode(ST, key, value, n.left)
}
case 2:
if n.right == nil {
n.right = new(Node)
n.right.key = key
n.right.value = value
n.right.parent = n
return n.right
} else {
return InsertNode(ST, key, value, n.right)
}
}
return nil
}
func Delete(ST SplayTree, key interface{}) error {
n := Search(ST, key)
if n == nil {
s := fmt.Sprintf("splay.Delete Error: key %v does not exist", key)
return errors.New(s)
} else {
p := n.parent
if n.left != nil {
iop := InOrderPredecessor(n.left)
Swap(n, iop)
Remove(ST, iop)
} else if n.right != nil {
ios := InOrderSuccessor(n.right)
Swap(n, ios)
Remove(ST, ios)
} else {
Remove(ST, n)
}
if p != nil {
Splay(ST, p)
}
return nil
}
}
func Swap(n1, n2 *Node) {
n1.key, n2.key = n2.key, n1.key
n1.value, n2.value = n2.value, n1.value
}
func Remove(ST SplayTree, n *Node) {
var isRoot, isLeft bool
isRoot = (n == ST.GetRoot())
if isRoot != true {
isLeft = (n == n.parent.left)
}
if isRoot != true {
if isLeft == true {
if n.left != nil {
n.parent.left = n.left
n.left.parent = n.parent
} else if n.right != nil {
n.parent.left = n.right
n.right.parent = n.parent
} else {
n.parent.left = nil
}
} else {
if n.left != nil {
n.parent.right = n.left
n.left.parent = n.parent
} else if n.right != nil {
n.parent.right = n.right
n.right.parent = n.parent
} else {
n.parent.right = nil
}
}
}
n = nil
}
func InOrderPredecessor(n *Node) *Node {
if n.right == nil {
return n
} else {
return InOrderPredecessor(n.right)
}
}
func InOrderSuccessor(n *Node) *Node {
if n.left == nil {
return n
} else {
return InOrderSuccessor(n.left)
}
}
func Splay(ST SplayTree, n *Node) {
for n != ST.GetRoot() {
if n.parent == ST.GetRoot() && n.parent.left == n {
ZigL(ST, n)
} else if n.parent == ST.GetRoot() && n.parent.right == n {
ZigR(ST, n)
} else if n.parent.left == n && n.parent.parent.left == n.parent {
ZigZigL(ST, n)
} else if n.parent.right == n && n.parent.parent.right == n.parent {
ZigZigR(ST, n)
} else if n.parent.right == n && n.parent.parent.left == n.parent {
ZigZagLR(ST, n)
} else {
ZigZagRL(ST, n)
}
}
}
func ZigL(ST SplayTree, n *Node) {
n.parent.left = n.right
if n.right != nil {
n.right.parent = n.parent
}
n.parent.parent = n
n.right = n.parent
n.parent = nil
ST.SetRoot(n)
}
func ZigR(ST SplayTree, n *Node) {
n.parent.right = n.left
if n.left != nil {
n.left.parent = n.parent
}
n.parent.parent = n
n.left = n.parent
n.parent = nil
ST.SetRoot(n)
}
func ZigZigL(ST SplayTree, n *Node) {
gg := n.parent.parent.parent
var isRoot, isLeft bool
if gg == nil {
isRoot = true
} else {
isRoot = false
isLeft = (gg.left == n.parent.parent)
}
n.parent.parent.left = n.parent.right
if n.parent.right != nil {
n.parent.right.parent = n.parent.parent
}
n.parent.left = n.right
if n.right != nil {
n.right.parent = n.parent
}
n.parent.right = n.parent.parent
n.parent.parent.parent = n.parent
n.right = n.parent
n.parent.parent = n
n.parent = gg
if isRoot == true {
ST.SetRoot(n)
} else if isLeft == true {
gg.left = n
} else {
gg.right = n
}
}
func ZigZigR(ST SplayTree, n *Node) {
gg := n.parent.parent.parent
var isRoot, isLeft bool
if gg == nil {
isRoot = true
} else {
isRoot = false
isLeft = (gg.left == n.parent.parent)
}
n.parent.parent.right = n.parent.left
if n.parent.left != nil {
n.parent.left.parent = n.parent.parent
}
n.parent.right = n.left
if n.left != nil {
n.left.parent = n.parent
}
n.parent.left = n.parent.parent
n.parent.parent.parent = n.parent
n.left = n.parent
n.parent.parent = n
n.parent = gg
if isRoot == true {
ST.SetRoot(n)
} else if isLeft == true {
gg.left = n
} else {
gg.right = n
}
}
func ZigZagLR(ST SplayTree, n *Node) {
gg := n.parent.parent.parent
var isRoot, isLeft bool
if gg == nil {
isRoot = true
} else {
isRoot = false
isLeft = (gg.left == n.parent.parent)
}
n.parent.parent.left = n.right
if n.right != nil {
n.right.parent = n.parent.parent
}
n.parent.right = n.left
if n.left != nil {
n.left.parent = n.parent
}
n.left = n.parent
n.right = n.parent.parent
n.parent.parent.parent = n
n.parent.parent = n
n.parent = gg
if isRoot == true {
ST.SetRoot(n)
} else if isLeft == true {
gg.left = n
} else {
gg.right = n
}
}
func ZigZagRL(ST SplayTree, n *Node) {
gg := n.parent.parent.parent
var isRoot, isLeft bool
if gg == nil {
isRoot = true
} else {
isRoot = false
isLeft = (gg.left == n.parent.parent)
}
n.parent.parent.right = n.left
if n.left != nil {
n.left.parent = n.parent.parent
}
n.parent.left = n.right
if n.right != nil {
n.right.parent = n.parent
}
n.right = n.parent
n.left = n.parent.parent
n.parent.parent.parent = n
n.parent.parent = n
n.parent = gg
if isRoot == true {
ST.SetRoot(n)
} else if isLeft == true {
gg.left = n
} else {
gg.right = n
}
}
func Print(ST SplayTree) {
PrintNode(ST.GetRoot(), 0) // Prints a directory-looking picture of ST to stdout
}
func PrintNode(n *Node, d int) {
if n == nil {
return
}
fmt.Println(strings.Repeat("-", 2*d), n.key, n.value)
PrintNode(n.left, d+1)
PrintNode(n.right, d+1)
}

@ -0,0 +1,52 @@
package main
// run go run splaytree_main.go in terminal
import (
"fmt"
"math/rand"
"./splay"
)
type Tree struct {
root *splay.Node
}
func (ST *Tree) SetRoot(n *splay.Node) {
ST.root = n
}
func (ST *Tree) GetRoot() *splay.Node {
return ST.root
}
func (ST *Tree) Ord(key1, key2 interface{}) int {
if key1.(int) < key2.(int) {
return 0
} else if key1.(int) == key2.(int) {
return 1
} else {
return 2
}
}
func main() {
ST := new(Tree)
for i := 0; i < 30; i++ {
err := splay.Insert(ST, rand.Int()%100, "hello")
if err != nil {
fmt.Println(err)
} else {
splay.Print(ST)
}
}
for i := 0; i < 30; i++ {
err := splay.Delete(ST, i)
if err != nil {
fmt.Println(err)
} else {
splay.Print(ST)
}
}
}
Loading…
Cancel
Save