diff --git a/datastructure/tree/bstree.go b/datastructure/tree/bstree.go index fcd09f7..9362456 100644 --- a/datastructure/tree/bstree.go +++ b/datastructure/tree/bstree.go @@ -10,7 +10,7 @@ import ( // BSTree is a binary search tree data structure in which each node has at most two children, // which are referred to as the left child and the right child. // In BSTree: leftNode < rootNode < rightNode -// type T should implments Compare function of lancetconstraints.Comparator interface +// type T should implements Compare function in lancetconstraints.Comparator interface. type BSTree[T any] struct { root *datastructure.TreeNode[T] } @@ -43,6 +43,21 @@ func (t *BSTree[T]) NodeLevel(node *datastructure.TreeNode[T]) int { return int(math.Max(left, right)) + 1 } +// PreOrderTraverse traverse tree node in pre order +func (t *BSTree[T]) PreOrderTraverse() []T { + return preOrderTraverse(t.root) +} + +// PostOrderTraverse traverse tree node in post order +func (t *BSTree[T]) PostOrderTraverse() []T { + return postOrderTraverse(t.root) +} + +// InOrderTraverse traverse tree node in mid order +func (t *BSTree[T]) InOrderTraverse() []T { + return inOrderTraverse(t.root) +} + // Print the bstree structure func (t *BSTree[T]) Print() { maxLevel := t.NodeLevel(t.root) diff --git a/datastructure/tree/bstree_test.go b/datastructure/tree/bstree_test.go index 346b61c..626a88b 100644 --- a/datastructure/tree/bstree_test.go +++ b/datastructure/tree/bstree_test.go @@ -1,6 +1,10 @@ package datastructure -import "testing" +import ( + "testing" + + "github.com/duke-git/lancet/internal" +) type intComparator struct{} @@ -27,3 +31,51 @@ func TestBSTree_Insert(t *testing.T) { bstree.Print() } + +func TestBSTree_PreOrderTraverse(t *testing.T) { + assert := internal.NewAssert(t, "TestBSTree_PreOrderTraverse") + + bstree := NewBSTree(6) + + comparator := &intComparator{} + bstree.Insert(7, comparator) + bstree.Insert(5, comparator) + bstree.Insert(2, comparator) + bstree.Insert(4, comparator) + + acturl := bstree.PreOrderTraverse() + t.Log(acturl) + assert.Equal([]int{6, 5, 2, 4, 7}, acturl) +} + +func TestBSTree_PostOrderTraverse(t *testing.T) { + assert := internal.NewAssert(t, "TestBSTree_PostOrderTraverse") + + bstree := NewBSTree(6) + + comparator := &intComparator{} + bstree.Insert(7, comparator) + bstree.Insert(5, comparator) + bstree.Insert(2, comparator) + bstree.Insert(4, comparator) + + acturl := bstree.PostOrderTraverse() + t.Log(acturl) + assert.Equal([]int{5, 2, 4, 7, 6}, acturl) +} + +func TestBSTree_InOrderTraverse(t *testing.T) { + assert := internal.NewAssert(t, "TestBSTree_InOrderTraverse") + + bstree := NewBSTree(6) + + comparator := &intComparator{} + bstree.Insert(7, comparator) + bstree.Insert(5, comparator) + bstree.Insert(2, comparator) + bstree.Insert(4, comparator) + + acturl := bstree.InOrderTraverse() + t.Log(acturl) + assert.Equal([]int{2, 4, 5, 6, 7}, acturl) +} diff --git a/datastructure/tree/tree_internal.go b/datastructure/tree/tree_internal.go index 1a7b956..dfbb4fb 100644 --- a/datastructure/tree/tree_internal.go +++ b/datastructure/tree/tree_internal.go @@ -8,6 +8,66 @@ import ( "github.com/duke-git/lancet/lancetconstraints" ) +func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T { + data := []T{} + if node != nil { + data = append(data, node.Data) + data = append(data, preOrderTraverse(node.Left)...) + data = append(data, preOrderTraverse(node.Right)...) + } + return data +} + +func postOrderTraverse[T any](node *datastructure.TreeNode[T]) []T { + data := []T{} + if node != nil { + data = append(data, preOrderTraverse(node.Left)...) + data = append(data, preOrderTraverse(node.Right)...) + data = append(data, node.Data) + } + return data +} + +func inOrderTraverse[T any](node *datastructure.TreeNode[T]) []T { + data := []T{} + if node != nil { + data = append(data, inOrderTraverse(node.Left)...) + data = append(data, node.Data) + data = append(data, inOrderTraverse(node.Right)...) + } + return data +} + +func preOrderPrint[T any](node *datastructure.TreeNode[T]) { + if node == nil { + return + } + + fmt.Printf("%v, ", node.Data) + preOrderPrint(node.Left) + preOrderPrint(node.Right) +} + +func postOrderPrint[T any](node *datastructure.TreeNode[T]) { + if node == nil { + return + } + + preOrderPrint(node.Left) + preOrderPrint(node.Right) + fmt.Printf("%v, ", node.Data) +} + +func inOrderPrint[T any](node *datastructure.TreeNode[T]) { + if node == nil { + return + } + + inOrderPrint(node.Left) + fmt.Printf("%v, ", node.Data) + inOrderPrint(node.Right) +} + func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) { if comparator.Compare(newNode.Data, rootNode.Data) == -1 { if rootNode.Left == nil {