Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
166
Task/AVL-tree/Go/avl-tree-1.go
Normal file
166
Task/AVL-tree/Go/avl-tree-1.go
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
package avl
|
||||
|
||||
// AVL tree adapted from Julienne Walker's presentation at
|
||||
// http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx.
|
||||
// This port uses similar indentifier names.
|
||||
|
||||
// The Key interface must be supported by data stored in the AVL tree.
|
||||
type Key interface {
|
||||
Less(Key) bool
|
||||
Eq(Key) bool
|
||||
}
|
||||
|
||||
// Node is a node in an AVL tree.
|
||||
type Node struct {
|
||||
Data Key // anything comparable with Less and Eq.
|
||||
Balance int // balance factor
|
||||
Link [2]*Node // children, indexed by "direction", 0 or 1.
|
||||
}
|
||||
|
||||
// A little readability function for returning the opposite of a direction,
|
||||
// where a direction is 0 or 1. Go inlines this.
|
||||
// Where JW writes !dir, this code has opp(dir).
|
||||
func opp(dir int) int {
|
||||
return 1 - dir
|
||||
}
|
||||
|
||||
// single rotation
|
||||
func single(root *Node, dir int) *Node {
|
||||
save := root.Link[opp(dir)]
|
||||
root.Link[opp(dir)] = save.Link[dir]
|
||||
save.Link[dir] = root
|
||||
return save
|
||||
}
|
||||
|
||||
// double rotation
|
||||
func double(root *Node, dir int) *Node {
|
||||
save := root.Link[opp(dir)].Link[dir]
|
||||
|
||||
root.Link[opp(dir)].Link[dir] = save.Link[opp(dir)]
|
||||
save.Link[opp(dir)] = root.Link[opp(dir)]
|
||||
root.Link[opp(dir)] = save
|
||||
|
||||
save = root.Link[opp(dir)]
|
||||
root.Link[opp(dir)] = save.Link[dir]
|
||||
save.Link[dir] = root
|
||||
return save
|
||||
}
|
||||
|
||||
// adjust valance factors after double rotation
|
||||
func adjustBalance(root *Node, dir, bal int) {
|
||||
n := root.Link[dir]
|
||||
nn := n.Link[opp(dir)]
|
||||
switch nn.Balance {
|
||||
case 0:
|
||||
root.Balance = 0
|
||||
n.Balance = 0
|
||||
case bal:
|
||||
root.Balance = -bal
|
||||
n.Balance = 0
|
||||
default:
|
||||
root.Balance = 0
|
||||
n.Balance = bal
|
||||
}
|
||||
nn.Balance = 0
|
||||
}
|
||||
|
||||
func insertBalance(root *Node, dir int) *Node {
|
||||
n := root.Link[dir]
|
||||
bal := 2*dir - 1
|
||||
if n.Balance == bal {
|
||||
root.Balance = 0
|
||||
n.Balance = 0
|
||||
return single(root, opp(dir))
|
||||
}
|
||||
adjustBalance(root, dir, bal)
|
||||
return double(root, opp(dir))
|
||||
}
|
||||
|
||||
func insertR(root *Node, data Key) (*Node, bool) {
|
||||
if root == nil {
|
||||
return &Node{Data: data}, false
|
||||
}
|
||||
dir := 0
|
||||
if root.Data.Less(data) {
|
||||
dir = 1
|
||||
}
|
||||
var done bool
|
||||
root.Link[dir], done = insertR(root.Link[dir], data)
|
||||
if done {
|
||||
return root, true
|
||||
}
|
||||
root.Balance += 2*dir - 1
|
||||
switch root.Balance {
|
||||
case 0:
|
||||
return root, true
|
||||
case 1, -1:
|
||||
return root, false
|
||||
}
|
||||
return insertBalance(root, dir), true
|
||||
}
|
||||
|
||||
// Insert a node into the AVL tree.
|
||||
// Data is inserted even if other data with the same key already exists.
|
||||
func Insert(tree **Node, data Key) {
|
||||
*tree, _ = insertR(*tree, data)
|
||||
}
|
||||
|
||||
func removeBalance(root *Node, dir int) (*Node, bool) {
|
||||
n := root.Link[opp(dir)]
|
||||
bal := 2*dir - 1
|
||||
switch n.Balance {
|
||||
case -bal:
|
||||
root.Balance = 0
|
||||
n.Balance = 0
|
||||
return single(root, dir), false
|
||||
case bal:
|
||||
adjustBalance(root, opp(dir), -bal)
|
||||
return double(root, dir), false
|
||||
}
|
||||
root.Balance = -bal
|
||||
n.Balance = bal
|
||||
return single(root, dir), true
|
||||
}
|
||||
|
||||
func removeR(root *Node, data Key) (*Node, bool) {
|
||||
if root == nil {
|
||||
return nil, false
|
||||
}
|
||||
if root.Data.Eq(data) {
|
||||
switch {
|
||||
case root.Link[0] == nil:
|
||||
return root.Link[1], false
|
||||
case root.Link[1] == nil:
|
||||
return root.Link[0], false
|
||||
}
|
||||
heir := root.Link[0]
|
||||
for heir.Link[1] != nil {
|
||||
heir = heir.Link[1]
|
||||
}
|
||||
root.Data = heir.Data
|
||||
data = heir.Data
|
||||
}
|
||||
dir := 0
|
||||
if root.Data.Less(data) {
|
||||
dir = 1
|
||||
}
|
||||
var done bool
|
||||
root.Link[dir], done = removeR(root.Link[dir], data)
|
||||
if done {
|
||||
return root, true
|
||||
}
|
||||
root.Balance += 1 - 2*dir
|
||||
switch root.Balance {
|
||||
case 1, -1:
|
||||
return root, true
|
||||
case 0:
|
||||
return root, false
|
||||
}
|
||||
return removeBalance(root, dir)
|
||||
}
|
||||
|
||||
// Remove a single item from an AVL tree.
|
||||
// If key does not exist, function has no effect.
|
||||
func Remove(tree **Node, data Key) {
|
||||
*tree, _ = removeR(*tree, data)
|
||||
}
|
||||
43
Task/AVL-tree/Go/avl-tree-2.go
Normal file
43
Task/AVL-tree/Go/avl-tree-2.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"avl"
|
||||
)
|
||||
|
||||
type intKey int
|
||||
|
||||
// satisfy avl.Key
|
||||
func (k intKey) Less(k2 avl.Key) bool { return k < k2.(intKey) }
|
||||
func (k intKey) Eq(k2 avl.Key) bool { return k == k2.(intKey) }
|
||||
|
||||
// use json for cheap tree visualization
|
||||
func dump(tree *avl.Node) {
|
||||
b, err := json.MarshalIndent(tree, "", " ")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
|
||||
func main() {
|
||||
var tree *avl.Node
|
||||
fmt.Println("Empty tree:")
|
||||
dump(tree)
|
||||
|
||||
fmt.Println("\nInsert test:")
|
||||
avl.Insert(&tree, intKey(3))
|
||||
avl.Insert(&tree, intKey(1))
|
||||
avl.Insert(&tree, intKey(4))
|
||||
avl.Insert(&tree, intKey(1))
|
||||
avl.Insert(&tree, intKey(5))
|
||||
dump(tree)
|
||||
|
||||
fmt.Println("\nRemove test:")
|
||||
avl.Remove(&tree, intKey(3))
|
||||
avl.Remove(&tree, intKey(1))
|
||||
dump(tree)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue