Notes On BST Operations
Notes On BST Operations
Notes On BST Operations
Attention: It is just the idea. You must check yourself the below code.
1. Introduction
Node = struct of members: parent
• label: LabelType
• left, right, parent: Node pointer left right
Tree T;
T = buildATree(); //Build a tree and let T point to the root of the tree
T A
B C
D E F
int main() {
Tree T;
T = buildATree(); //Build a tree and
//let T point to the root of the tree
foo(T); //Pass value of T (address of node) to root
...
}
1/17
In this case, root and T are two different pointers (two different arrows) which point to a
same node (i.e., root).
root
T
A
B C
D E F
Because T and root point to the same node, if we change the content of the node using
root, for example, make set the label of the node to ‘X’, T->label will change.
int main() {
Tree T;
T = buildATree(); //Build a tree and
//let T point to the root of the tree
foo(T);
...
}
root
T
X
B C
D E F
2/17
However, if we change root, for example, make root point to another node, T rests
unchanged!
int main() {
Tree T;
T = buildATree(); //Build a tree and
//let T point to the root of the tree
foo(T);
...
}
root
T
A
x
A C
D E F
3/17
b. Pass a tree as an address
“Address can be considered as another name (alias) of a variable.”
int main() {
Tree T;
T = buildATree(); //Build a tree and
//let T point to the root of the tree
foo(&T); //Pass address of T to pT
…
}
Now, pT and T are different pointers but T and (*pT) are the same pointer. So, we can say
that (*pT) is another name of T.
(*pT) pT
T
A
A C
D E F
4/17
1. makeNull(T) – makes T be an empty tree
In this function, we want to make the pointer T point to NULL. So we must change T in the
makeNull() function. There is only one way to do this, that is passing T by address!
int main() {
Tree T;
T = buildATree(); //Build a tree and
//let T point to the root of the tree
makeNull(&T); //Pass address of T to root
…
}
(*pT) pT (*pT) pT
T T
A NULL
A C
D E F
Before After
5/17
If we try to pass T as value, the result is not what we want.
int main() {
Tree T;
T = buildATree(); //Build a tree and
//let T point to the root of the tree
makeNull(T); //Pass value of T to root
...
}
root root
T T
A A
NULL
A C A C
D E F D E F
Before After
6/17
2. insert(x, T) – inserts x into tree T
• If T is a null tree (a null pointer), inserting a new node makes T point to the new
node. Therefore, T must be changed.
• If T is not null, inserting a new node will change the content of some node.
Case 2:
//2a. Find a right position to insert
//2b. Insert a new node
}
Find a right position to insert x into tree T, can be done by loop or recursion.
a. Using loop
We start from root of T (i.e., *pT).
Loop until node is NULL (we left the tree) or node contains x. In the loop we compare x to
node->label and go left or right according to comparison result.
When the loop finishes, “parent” is the last node we meet before leaving the tree.
Depending on relation between x and parent->label, we will insert x into the left or the right
of parent.
7/17
insert 7
1
0
parent
5 2
0
4 8 1
5
1 1
4 8
If x = parent->label, x has been existed in T, just return.
The next step is to create a new node, place x, and set parent->left or parent->right point to
the new node.
8/17
void insert(LabelType x, Tree *pT) {
Case 1: If *pT is a null tree,
if (*pT == NULL) {
//1a. create a node,
Node *root = (Node*)malloc(sizeof(Node);
//1b. place x and
root->label = x;
//1c. make *pT point to the new node
(*pT) = root;
return;
}
Case 2:
//2a. Find a right position to insert
Node *node = *pT, *parent;
while (node != NULL) {
parent = node;
if (x == node->label) break;
if (x < node->label)
node = node->left;
else
node = node->right;
}
if (x == parent->label) return; //x existed in T
b. Using recursion
Recursive version is a bit difficult to understand in compared to loop version, but it’s very
compact and clean. 😉
Just compare x to label of the root (i.e., (*pT)->label) and use recursion
If x == (*pT)->label => return
If x < ((*pT)->label) => recursively insert x into the left subtree of (*pT)
else => recursively insert x into the right subtree of (*pT)
9/17
void insert(LabelType x, Tree *pT) {
Case 1: If *pT is a null tree,
if (*pT == NULL) {
//1a. create a node,
Node *root = (Node*)malloc(sizeof(Node);
//1b. place x and
root->label = x;
//1c. make *pT point to the new node
(*pT) = root;
return;
}
10/17
3. delete(x, T) – deletes x from tree T
• If the deleted node is root, T must be changed.
• Otherwise, we change the content of some node.
a. Using loop
We will find the node containing x and its parent.
Loop until node is NULL (we left the tree) or node contains x. In the loop we compare x to
node->label and go left or right according to comparison result.
When the loop finishes, if node == NULL, x does not appear in T, just return.
11/17
delete 8
parent
1
0
node
5 2
0
4 8 1
5
1 1
4 8
To delete the node “node”, there are 3 cases to consider:
if (parent == NULL)
*pT = NULL; //Tree has only one node
else if (node == parent->left)
parent->left = NULL;
else
parent->right = NULL;
node->label = deleteMin(&(node->right));
12/17
Case 3: “node” has one child
• Take the unique child of “node”
• Set parent->left or parent->right to the child. Beware of the case parent == NULL.
Node *child;
if (node->left == NULL)
child = node->right;
else
child = node->left;
if (parent == NULL)
(*pT) = child;
else if (node == parent->left)
parent->left = child;
else
parent->right = child;
13/17
void delete(LabelType x, Tree *pT) {
if ((*pT) == NULL) return;
if (parent == NULL)
(*pT) = child;
else if node = parent->left)
parent->left = child;
else
parent->right = child;
14/17
b. Using recursion
Instead of using loop to find the node to be deleted, we compare x to (*pT)->label and
recursively delete x from the left subtree or the right subtree.
(*pT) = child;
}
}
15/17
4. deleteMin(T) – deletes the smallest node from T (T is not empty)
Step 2: delete it
}
a. Using loop
To find the smallest node, from the root, we go left until node->left == NULL. We must also
keep the parent of the node.
Because node->left == NULL (as case 3 in delete function), we will set parent->left or parent-
>right to node->right.
return node->label;
}
16/17
b. Using recursion
• If (*pT)->left != NULL, (*pT) is the node to be delete
• Otherwise, recursively delete the left subtree
Case 2:
return deleteMin(&((*pT)->left));
}
17/17