added test fot AvlTree and implemented inorder, postorder traversal
Go / build (push) Successful in 34s
Go / build (push) Successful in 34s
This commit is contained in:
+80
-15
@@ -1,31 +1,30 @@
|
||||
package avl
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
|
||||
type numericTypes interface {
|
||||
int | int8 | int16 | int32 | int64 |
|
||||
uint | uint8 | uint16 | uint32 | uint64 |
|
||||
float32 | float64
|
||||
}
|
||||
"datastructures/linear"
|
||||
)
|
||||
|
||||
type AvlNode[T numericTypes] struct {
|
||||
type AvlNode[T cmp.Ordered] struct {
|
||||
Left *AvlNode[T]
|
||||
Right *AvlNode[T]
|
||||
Data T
|
||||
Height int
|
||||
}
|
||||
|
||||
type AvlTree[T numericTypes] struct {
|
||||
type AvlTree[T cmp.Ordered] struct {
|
||||
Root *AvlNode[T]
|
||||
}
|
||||
|
||||
// NewAvlTree() -> creates an AVL tree
|
||||
func NewAvlTree[T numericTypes]() *AvlTree[T] {
|
||||
func NewAvlTree[T cmp.Ordered]() *AvlTree[T] {
|
||||
return &AvlTree[T]{}
|
||||
}
|
||||
|
||||
// height() -> 0 if root
|
||||
func height[T numericTypes](n *AvlNode[T]) int {
|
||||
func height[T cmp.Ordered](n *AvlNode[T]) int {
|
||||
if n == nil {
|
||||
return 0
|
||||
}
|
||||
@@ -33,12 +32,12 @@ func height[T numericTypes](n *AvlNode[T]) int {
|
||||
}
|
||||
|
||||
// updateHeight()
|
||||
func updateHeight[T numericTypes](node *AvlNode[T]) {
|
||||
func updateHeight[T cmp.Ordered](node *AvlNode[T]) {
|
||||
node.Height = 1 + max(height(node.Left), height(node.Right))
|
||||
}
|
||||
|
||||
// balanceFactor() -> only 0 , -1 ,-2 ok
|
||||
func balanceFactor[T numericTypes](n *AvlNode[T]) int {
|
||||
func balanceFactor[T cmp.Ordered](n *AvlNode[T]) int {
|
||||
if n == nil {
|
||||
return 0
|
||||
}
|
||||
@@ -47,7 +46,7 @@ func balanceFactor[T numericTypes](n *AvlNode[T]) int {
|
||||
}
|
||||
|
||||
// rotateRight() -> fixes a left heavy subtree, returns the new subtree root
|
||||
func rotateRight[T numericTypes](y *AvlNode[T]) *AvlNode[T] {
|
||||
func rotateRight[T cmp.Ordered](y *AvlNode[T]) *AvlNode[T] {
|
||||
x := y.Left
|
||||
b := x.Right
|
||||
|
||||
@@ -61,7 +60,7 @@ func rotateRight[T numericTypes](y *AvlNode[T]) *AvlNode[T] {
|
||||
}
|
||||
|
||||
// rotateLeft() -> fixes a right heavy subtree, returns the new subtree root
|
||||
func rotateLeft[T numericTypes](x *AvlNode[T]) *AvlNode[T] {
|
||||
func rotateLeft[T cmp.Ordered](x *AvlNode[T]) *AvlNode[T] {
|
||||
y := x.Right
|
||||
b := y.Left
|
||||
|
||||
@@ -79,7 +78,7 @@ func (tree *AvlTree[T]) Insert(data T) {
|
||||
tree.Root = insertHelper(tree.Root, data)
|
||||
}
|
||||
|
||||
func insertHelper[T numericTypes](node *AvlNode[T], data T) *AvlNode[T] {
|
||||
func insertHelper[T cmp.Ordered](node *AvlNode[T], data T) *AvlNode[T] {
|
||||
// normal BST insert
|
||||
if node == nil {
|
||||
return &AvlNode[T]{Data: data, Height: 1}
|
||||
@@ -136,6 +135,72 @@ func (t AvlTree[T]) Find(val T) (*AvlNode[T], bool) {
|
||||
return zero, false
|
||||
}
|
||||
|
||||
// Traversals
|
||||
|
||||
// TraverseInorder() -> in order traversal of avl tree starting at root, returns a slice of
|
||||
// AvlNode.Data. Iterative, no recursion.
|
||||
func (tree *AvlTree[T]) TraverseInorder() []T {
|
||||
var list []T
|
||||
stack := linear.Stack[*AvlNode[T]]{}
|
||||
|
||||
current := tree.Root
|
||||
|
||||
// every node on the stack has been walked past but not emitted yet
|
||||
for current != nil || stack.Size() > 0 {
|
||||
|
||||
// dive left
|
||||
for current != nil {
|
||||
stack.Push(current)
|
||||
current = current.Left
|
||||
}
|
||||
|
||||
node, err := stack.Pop()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
list = append(list, node.Data)
|
||||
|
||||
current = node.Right
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// TraversePreorder() -> pre order traversal of avl tree starting at root, returns a slice of
|
||||
// AvlNode.Data
|
||||
func (tree *AvlTree[T]) TraversePreorder() []T {
|
||||
var list []T
|
||||
stack := linear.Stack[*AvlNode[T]]{}
|
||||
|
||||
if tree.Root == nil {
|
||||
return list
|
||||
}
|
||||
|
||||
stack.Push(tree.Root)
|
||||
|
||||
for stack.Size() > 0 {
|
||||
|
||||
root, err := stack.Pop()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
list = append(list, root.Data)
|
||||
|
||||
if root.Right != nil {
|
||||
stack.Push(root.Right)
|
||||
}
|
||||
|
||||
if root.Left != nil {
|
||||
stack.Push(root.Left)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// Display() -> draws the tree rotated 90° left: right subtree on top,
|
||||
// left subtree on the bottom, connected with box-drawing characters.
|
||||
// Iterative , no recursion.
|
||||
|
||||
Reference in New Issue
Block a user