trees

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2021 License: MIT Imports: 2 Imported by: 1

README

Trees

This readme introduces some common trees including

  • Binary Search Tree
  • Max(Min) Heap

Binary Search Tree

Binary Search Tree has the following properties:

  • The values in left sub-tree nodes are always smaller than the value in the root.
  • The values in the right sub-tree nodes are always bigger than the value in the root.
Insert

To insert a node into a binary search tree, just compare it with the current root, if it's smaller than the root, insert it into the left sub-tree, otherwise, insert into the right sub-tree. The time complexity is O(logN), the worse case scenario is O(N), in which case, the tree is extremely unbalanced and is essentially a linked list. The space complexity is O(N).

To search a node, it's the same of insertion, starting from the root, if the value matches, return; if the value is smaller than the root's value, search it recursively in the left sub-tree; if the value is bigger than the root's value, search it recursively in the right sub-tree. The time complexity is O(logN), the worse case scenario is O(N), in which case, the tree is extremely unbalanced and is essentially a linked list. The space complexity is O(N).

Deletion

Deleting a node is tricky, first of all, find the node by the searching method. When the node is found, there are a few cases:

  • The node is a leaf: we point the parent of this node to nil.
  • The node has only left child: we point parent of this node to its left child.
  • The node has only right child: we point parent of this node to its right child.
  • The node has both children:
    • We find the maximum value in the node's left sub-tree.
    • We assign this value to the node.
    • We point the node's parent to the maximum node's left sub-tree.

Tips: To make the deletion work, we make a fake parent who's right child is the root to start with.

The time complexity is O(logN), but the same as the above, worse case is O(N). The space complexity is O(N).

Max(Min) Heap

Heap has the following properties:

  • A heap is a Complete Binary Tree
  • For a given node in a heap, the values of the nodes for its children are always smaller&bigger than this node's value, for Max and Min heap respectively.
  • The sub-trees of a node are also heaps.

Notes: The best way to store a heap is using an array list. for a given node with index i, the left child is i * 2, the right child is i * 2 + 1 for a given node with index i, the parent node is i / 2. The root node is at index 1. We can use list[0] as a functional slot in heap operations.

For the following section, we assume it's a Max heap, for Min heap it's all the same, only the comparison is the other way round.

Build Heap For a List

To build a heap from a given list, we do the following:

  • Start from the parent of the last node, and loop back toward the root of the heap, for each of them:

    • If the node doesn't have left node, finish.
    • Find the node with larger value, let it be left or right.
    • If this value is not bigger than the value of the node, finish.
    • Otherwise switch the value, and let the current node to be this node.
    • Repeat.

    The time complexity of this operation is O(N). The space complexity of this operation is O(N).

Insert

To insert a node into a heap, just attach it to the end of the list, which makes it the last leaf node. Then we do the following to make sure the heap is still valid:

  • Start from the last leaf node you just added.
  • Compare the node with its parent's value, if this value is bigger than the value of its parent, switch the value.
  • Let the parent node be the current one, repeat the last operation unless we reach the root.

The time complexity of this operation is O(logN). The space complexity of this operation is O(N).

Peek/Pop

Peek is just to get the value of the top node. Pop is to assign the value of the last node to the top node, and remove the last node. Then do the following:

  • Start from the root where index = 1

  • If the node has no children, finish.

  • Compare the value with its left and right child's value, get the large one, if it's the node itself, finish.

  • If the largest value is the left or right child, switch this value with the node, and left node = node with largest value, repeat.

  • The node is a leaf: we point the parent of this node to nil.

  • The node has only left child: we point parent of this node to its left child.

  • The node has only right child: we point parent of this node to its right child.

  • The node has both children:

    • We find the maximum value in the node's left sub-tree.
    • We assign this value to the node.
    • We point the node's parent to the maximum node's left sub-tree.

The time complexity of this operation is O(logN). The space complexity of this operation is O(N).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BTree

type BTree struct {
	Root *BTreeNode // root has min 2 children if it's not leaf.
	// contains filtered or unexported fields
}

BTree defines a B-Tree

func NewBTree

func NewBTree(order int, comparator shared.Comparator) *BTree

NewBTree creates a new B-Tree

func (*BTree) Clear

func (b *BTree) Clear()

Clear clears the B-Tree

func (*BTree) Delete

func (b *BTree) Delete(key interface{}) (value interface{}, err error)

Delete deletes the key (index) and its value from the B-Tree

func (*BTree) GetHeight

func (b *BTree) GetHeight() int

GetHeight gets the height of the B-Tree.

func (*BTree) GetSize

func (b *BTree) GetSize() int

GetSize gets the total number of values.

func (*BTree) Put

func (b *BTree) Put(key, value interface{})

Put puts an key (index) and it's value into the B-Tree, if the key exists, update the value

func (*BTree) Search

func (b *BTree) Search(key interface{}) (node *BTreeNode, index int, err error)

Search searchs the key (index) to get the value from the B-Tree

type BTreeNode

type BTreeNode struct {
	Keys     []interface{} // The separation keys, for non-leaf node, count = count(children) - 1
	Values   []interface{}
	Children []*BTreeNode // The childrens, maximum at order
	Parent   *BTreeNode
}

BTreeNode defines a B-Tree Node

type BinarySearchTree

type BinarySearchTree struct {
	BinaryTree
	// contains filtered or unexported fields
}

BinarySearchTree defines a binary search tree

func (*BinarySearchTree) Clear

func (b *BinarySearchTree) Clear()

Clear clears the binary search tree.

func (*BinarySearchTree) ConvertFromDoubleLinkedList

func (b *BinarySearchTree) ConvertFromDoubleLinkedList(head *BinaryTreeNode, length int)

ConvertFromDoubleLinkedList converts double linked list back to

func (*BinarySearchTree) ConvertToDoubleLinkedList

func (b *BinarySearchTree) ConvertToDoubleLinkedList() (head *BinaryTreeNode, tail *BinaryTreeNode)

ConvertToDoubleLinkedList converts the BST to A Double Linked List.

func (*BinarySearchTree) Delete

func (b *BinarySearchTree) Delete(data interface{}) error

Delete deletes a data node from binary search tree.

func (*BinarySearchTree) GetSize

func (b *BinarySearchTree) GetSize() int

GetSize gets the size of the tree.

func (*BinarySearchTree) Put

func (b *BinarySearchTree) Put(key, value interface{})

Put puts a data node into the binary search tree, if the key exists already, update its value.

func (*BinarySearchTree) Search

func (b *BinarySearchTree) Search(key interface{}) (value interface{})

Search searchs value by key.

func (*BinarySearchTree) ToSortedSlice

func (b *BinarySearchTree) ToSortedSlice() []interface{}

ToSortedSlice traverse the tree and store the data into a sorted slice

type BinaryTree

type BinaryTree struct {
	Root       *BinaryTreeNode
	Comparator shared.Comparator
}

BinaryTree defines a general binary tree

func (*BinaryTree) BreadthFirstTraverse

func (b *BinaryTree) BreadthFirstTraverse() []interface{}

BreadthFirstTraverse traverse the tree breadth-first way, a.k.a level by level. The idea is to use a QUEUE to store candidate left and right children along the way.

func (*BinaryTree) DepthFirstTraverse

func (b *BinaryTree) DepthFirstTraverse() []interface{}

DepthFirstTraverse traverse the tree depth-first way. The idea is to use a STACK to store candidate right and left children along the way.

type BinaryTreeNode

type BinaryTreeNode struct {
	Key   interface{}
	Value interface{}
	Left  *BinaryTreeNode
	Right *BinaryTreeNode
}

BinaryTreeNode defines a tree node of a binary search tree

type Heap

type Heap struct {
	HeapType HeapType

	Comparator shared.Comparator
	// contains filtered or unexported fields
}

Heap defines a heap

func (*Heap) GetValues

func (h *Heap) GetValues() []interface{}

GetValues gets the values of the heap

func (*Heap) InitHeap

func (h *Heap) InitHeap(values []interface{})

InitHeap initializes a heap using a list of values.

func (*Heap) Insert

func (h *Heap) Insert(data interface{})

Insert inserts a node into a heap

func (*Heap) Peek

func (h *Heap) Peek() interface{}

Peek returns the top value of the heap

func (*Heap) Pop

func (h *Heap) Pop() interface{}

Pop returns the top value of the heap.

type HeapType

type HeapType int

HeapType defines the heap type

const (
	HeapTypeMax HeapType = iota
	HeapTypeMin
)

Enum values of HeapType

type IndexedPriorityQueue

type IndexedPriorityQueue struct {
	// contains filtered or unexported fields
}

IndexedPriorityQueue defines an indexed priority queue based on a heap.

func NewIndexedPriorityQueue

func NewIndexedPriorityQueue(capacity int, heapType HeapType, comparator shared.Comparator) *IndexedPriorityQueue

NewIndexedPriorityQueue creates a new indexed priority queue with capacity, heapType and value comparator specified

func (*IndexedPriorityQueue) ChangeValue

func (i *IndexedPriorityQueue) ChangeValue(index int, value interface{}) error

ChangeValue changes the value at a given index, if the index is out of range or no value was added, error will be returned.

func (*IndexedPriorityQueue) Contains

func (i *IndexedPriorityQueue) Contains(index int) bool

Contains check whether the queue contains a value with the given index.

func (*IndexedPriorityQueue) DeleteValue

func (i *IndexedPriorityQueue) DeleteValue(index int) error

DeleteValue deletes the value at a given index, if the index is out of range or no value was added, error will be returned.

func (*IndexedPriorityQueue) GetValue

func (i *IndexedPriorityQueue) GetValue(index int) (interface{}, error)

GetValue gets value at a given index, if index is out of range or no value was added, error will be returned.

func (*IndexedPriorityQueue) Insert

func (i *IndexedPriorityQueue) Insert(index int, value interface{}) error

Insert inters a value into the queue with a given index, if the index is not valid or is taken, error will be return.

func (*IndexedPriorityQueue) IsEmpty

func (i *IndexedPriorityQueue) IsEmpty() bool

IsEmpty returns whether the queue is empty.

func (*IndexedPriorityQueue) Peek

func (i *IndexedPriorityQueue) Peek() (index int, value interface{}, err error)

Peek peeks the priority queue, it returns the heap top value with it's index. if queue is empty, error will be returned.

func (*IndexedPriorityQueue) Pop

func (i *IndexedPriorityQueue) Pop() (index int, value interface{}, err error)

Pop returns the heap top value of the queue, and remove it from the queue in the meantime, error will be returned if queue is empty.

func (*IndexedPriorityQueue) Size

func (i *IndexedPriorityQueue) Size() int

Size returns the number of values stored in the queue.

Jump to

Keyboard shortcuts

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