From 37c0cba1a31fae04108e5b0a6e038604b98ebce4 Mon Sep 17 00:00:00 2001 From: Faris CHTATOU Date: Mon, 16 Jan 2023 20:31:31 +0100 Subject: [PATCH] update tests and methods to add private parent field to bst --- tree/bst.go | 24 +++++++++++------------- tree/node.go | 27 ++++++++++++++++----------- tree/node_test.go | 28 ++++++++++++++++------------ 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/tree/bst.go b/tree/bst.go index 40b8630..37aba67 100644 --- a/tree/bst.go +++ b/tree/bst.go @@ -61,7 +61,7 @@ func (t *BinarySearchTree) Insert(data int) *Node { newNode := NewNode(data) if t.root == nil { - newNode.Parent = nil + newNode.parent = nil t.root = newNode return newNode } @@ -71,14 +71,14 @@ func (t *BinarySearchTree) Insert(data int) *Node { for currentNode != nil { if data <= currentNode.data { if currentNode.left == nil { - newNode.Parent = currentNode + newNode.parent = currentNode currentNode.left = newNode return newNode } currentNode = currentNode.left } else { if currentNode.right == nil { - newNode.Parent = currentNode + newNode.parent = currentNode currentNode.right = newNode return newNode } @@ -96,11 +96,9 @@ func (t *BinarySearchTree) Remove(data int) { } var currentNode *Node = t.root - var parentNode *Node = nil - + // Find the node to delete for currentNode != nil && currentNode.data != data { - parentNode = currentNode if currentNode.data > data { currentNode = currentNode.left } else { @@ -117,16 +115,16 @@ func (t *BinarySearchTree) Remove(data int) { return } else if currentNode.left != nil { // In this case the currentNode to delete only has a left child - currentNode.RemoveNodeWithOneChild(parentNode, t, Left) + currentNode.RemoveNodeWithOneChild(t, Left) return } else if currentNode.right != nil { // In this case the currentNode to delete only has a right child - currentNode.RemoveNodeWithOneChild(parentNode, t, Right) + currentNode.RemoveNodeWithOneChild(t, Right) return } else { // In this case the currentNode to delete has no child // We need to cut the relation - currentNode.RemoveLeafNode(parentNode, t) + currentNode.RemoveLeafNode(t) return } @@ -300,13 +298,13 @@ func (t *BinarySearchTree) FindInorderSuccessor(data int) *Node { return currentNode } else { - for currentNode.Parent != nil && currentNode.IsFromRight(currentNode.Parent) { - if currentNode.Parent.Parent == nil { + for currentNode.parent != nil && currentNode.IsFromRight() { + if currentNode.parent.parent == nil { return nil } - currentNode = currentNode.Parent + currentNode = currentNode.parent } - return currentNode.Parent + return currentNode.parent } } diff --git a/tree/node.go b/tree/node.go index e8a68a2..9391871 100644 --- a/tree/node.go +++ b/tree/node.go @@ -4,7 +4,7 @@ type Node struct { data int left *Node right *Node - Parent *Node + parent *Node } type Direction string @@ -31,8 +31,13 @@ func (n *Node) HasTwoChild() bool { } // IsFromRight returns true if the node is the right child of the parent. -func (n *Node) IsFromRight(parentNode *Node) bool { - return n == parentNode.right +func (n *Node) IsFromRight() bool { + + if n.parent == nil { + return false + } + + return n == n.parent.right } // RemoveNodeWithTwoChild removes a node with two children. @@ -57,7 +62,7 @@ func (currentNode *Node) RemoveNodeWithTwoChild() { } // RemoveNodeWithOneChild removes a node with one child. -func (currentNode *Node) RemoveNodeWithOneChild(parentNode *Node, t *BinarySearchTree, direction Direction) { +func (currentNode *Node) RemoveNodeWithOneChild(t *BinarySearchTree, direction Direction) { var newNode *Node = nil switch direction { case Left: @@ -68,20 +73,20 @@ func (currentNode *Node) RemoveNodeWithOneChild(parentNode *Node, t *BinarySearc if currentNode == t.root { t.root = newNode - } else if currentNode.IsFromRight(parentNode) { - parentNode.right = newNode + } else if currentNode.IsFromRight() { + currentNode.parent.right = newNode } else { - parentNode.left = newNode + currentNode.parent.left = newNode } } // RemoveNodeWithNoChild removes a node with no child. This is the case when the node is a leaf. In this case we just need to remove the reference to the node from the parent. -func (currentNode *Node) RemoveLeafNode(parentNode *Node, t *BinarySearchTree) { +func (currentNode *Node) RemoveLeafNode(t *BinarySearchTree) { if currentNode == t.root { t.root = nil - } else if currentNode.IsFromRight(parentNode) { - parentNode.right = nil + } else if currentNode.IsFromRight() { + currentNode.parent.right = nil } else { - parentNode.left = nil + currentNode.parent.left = nil } } diff --git a/tree/node_test.go b/tree/node_test.go index 01a9177..d9a5167 100644 --- a/tree/node_test.go +++ b/tree/node_test.go @@ -41,12 +41,15 @@ func TestNode_HasTwoChild(t *testing.T) { func TestNode_IsFromRight(t *testing.T) { node := NewNode(1) - parentNode := NewNode(2) - if node.IsFromRight(parentNode) { + childNode := NewNode(2) + + if childNode.IsFromRight() { t.Errorf("node is not from right") } - parentNode.right = node - if !node.IsFromRight(parentNode) { + + node.right = childNode + childNode.parent = node + if !childNode.IsFromRight() { t.Errorf("node is from right") } } @@ -70,7 +73,7 @@ func Test_RemoveRootNodeWithLeftChild(t *testing.T) { node.left = NewNode(5) tree.root = node - node.RemoveNodeWithOneChild(nil, tree, Left) + node.RemoveNodeWithOneChild(tree, Left) if tree.root.data != 5 { t.Errorf("Root node is not 5. Delete root node with left child") } @@ -82,7 +85,7 @@ func Test_RemoveRootNodeWithRightChild(t *testing.T) { node.right = NewNode(15) tree.root = node - node.RemoveNodeWithOneChild(nil, tree, Right) + node.RemoveNodeWithOneChild(tree, Right) if tree.root.data != 15 { t.Errorf("Root node is not 15. Delete root node with right child") } @@ -93,7 +96,7 @@ func Test_RemoveRootNodeWithNoChild(t *testing.T) { node := NewNode(10) tree.root = node - node.RemoveLeafNode(nil, tree) + node.RemoveLeafNode(tree) if tree.root != nil { t.Errorf("Root node is not nil. Delete root node with no child") } @@ -103,12 +106,13 @@ func Test_RemoveMiddleNodeWithLeftChild(t *testing.T) { tree := New(nil) parentNode := NewNode(10) currentNode := NewNode(5) + currentNode.parent = parentNode parentNode.left = currentNode currentNodeLeftChild := NewNode(3) currentNode.left = currentNodeLeftChild tree.root = parentNode - currentNode.RemoveNodeWithOneChild(parentNode, tree, Left) + currentNode.RemoveNodeWithOneChild(tree, Left) if parentNode.left.data != 3 { t.Errorf("Parent child node is not 3. Delete middle node with left child") } @@ -118,27 +122,27 @@ func Test_RemoveMiddleNodeWithRightChild(t *testing.T) { tree := New(nil) parentNode := NewNode(10) currentNode := NewNode(15) + currentNode.parent = parentNode parentNode.right = currentNode currentNodeRightChild := NewNode(25) currentNode.left = currentNodeRightChild tree.root = parentNode - currentNode.RemoveNodeWithOneChild(parentNode, tree, Left) + currentNode.RemoveNodeWithOneChild(tree, Left) if parentNode.right.data != 25 { t.Errorf("Parent child node is not 3. Delete middle node with right child") } } -// TODO : Test case for RemoveMiddleNodeWithTwoChild - func Test_RemoveLeafNode(t *testing.T) { tree := New(nil) parentNode := NewNode(10) currentNode := NewNode(5) parentNode.left = currentNode + currentNode.parent = parentNode tree.root = parentNode - currentNode.RemoveLeafNode(parentNode, tree) + currentNode.RemoveLeafNode(tree) if parentNode.left != nil { t.Errorf("Parent child node is not nil. Delete leaf node") }