O(1) O(log n) O(n) O(n log n) O(n2) AVL tree Splay tree Binary search tree Hash table Open addressing Separate chaining Linear probing Hash function Hash Table Size Rotation Collision Hash function Even number 2n-1 Prime number 2n
-----------------------
0 | 28 |
| |
-----------------------
1 | 22 |
| |
-----------------------
2 | 21 |
| |
-----------------------
3 | 17 |
| |
-----------------------
4 | 30 |
| |
-----------------------
5 | |
| |
-----------------------
6 | |
| |
-----------------------
-----------------------
0 | |
| |
-----------------------
1 | |--> 21
| |
-----------------------
2 | |--> 22, 17, 32
| |
-----------------------
3 | |--> 28
| |
-----------------------
4 | |
| |
-----------------------
---100---
/ \
50 -150-
/ / \
25 125 -300-
/ \
175 400
\
250
/ \
200 275
To delete 150 we must find the smallest child in its right subtree,
which is 175. 175 will get promoted to 150's spot but first we must
delete 175 from the tree. When we delete 175 its right child gets
promoted to 175's original spot as a descendent of 300. The final
tree becomes:
---100---
/ \
50 -175-
/ / \
25 125 -300-
/ \
250 400
/ \
200 275
-300-
/ \
175 400
\
250
/ \
200 275
The right rotation will cause 300 to become a right child of 175. In so doing
the right subtree rooted at 250 will become an orphan because 300 is taking
its place as 175's right child. Therefore 300 adopts 250 as its left child
while keeping 400 as its right child. Note that it is ok for 300 to adopt 250
as its left subtree because all of the values in 250's tree are less than 300.
The final tree becomes:
175
\
300
/ \
250 400
/ \
200 275
20
/ \
10 40
/ \
8 16
/
12
In the tree below I have labeled each node with its height.
Since 20 is the first node whose subtree heights differ by
more than 1, it is the first node to violate the AVL condition.
20 h = 3
/ \
h = 2 10 40 h = 0
/ \
h = 0 8 16 h = 1
/
12 h = 0
We must use the zig-zag case. If we follow the route of the path followed for the insertion of 12, we see that we first went left, to 10, and then right, to 16. This left-right traversal is a zig-zag.
We need to use a left-right double rotation since we have a left-right zig-zag. We will first do a left rotation about the grandchild of 20, which is 16, and then do a right rotation about 16:
20 16
/ \ / \
left rotation 16 40 right rotation 10 20
------------> / --------------> / \ \
10 8 12 40
/ \
8 12
The left rotation makes 10 be a left child of 16. 12 becomes
orphaned in this process and since 10's right child is now
freed up, 10 adopts 12 as its right child. The right rotation
makes 20 be a right child of 16. This rotation is fairly
simple since no orphans are created in the process and therefore
no adoptions are required.
14 19 16 26 21 19 68 65 31 32 44 23
----- 14 -----
/ \
19 16
/ \ / \
26 21 19 68
/ \ / \ /
65 31 32 44 23
Step 1: Insert 15 at the first available location:
----- 14 -----
/ \
19 16
/ \ / \
26 21 19 68
/ \ / \ / \
65 31 32 44 23 15
Step 2: Bubble up 15 until it is greater than or equal to its parent.
Since 15 is less than 19, we exchange 15 and 19:
----- 14 -----
/ \
19 16
/ \ / \
26 21 15 68
/ \ / \ / \
65 31 32 44 23 19
Step 3: 15 is less than 16 so we exchange 15 and 16:
----- 14 -----
/ \
19 15
/ \ / \
26 21 16 68
/ \ / \ / \
65 31 32 44 23 19
We are now finished because 15 is greater than 14. I could have shown
the intermediate steps as holes, and only inserted 15 at the end, but
I presented the solution like this to make it easier to follow.
Here is the original tree:
----- 14 -----
/ \
19 16
/ \ / \
26 21 19 68
/ \ / \ /
65 31 32 44 23
A deleteMin involves the following steps:
Step 1: Remove the root, 14, and set it aside. Promote the bottom-most, right-most node in the tree, 23, to be the new root:
----- 23 -----
/ \
19 16
/ \ / \
26 21 19 68
/ \ / \
65 31 32 44
Step 2: Push down 23 to re-establish the heap property. We first compare
23's two children 19 and 16. Since 16 is the smaller of the two children,
we compare 16 with 23. Since 16 is less than 23, we exchange 16 and 23:
----- 16 -----
/ \
19 23
/ \ / \
26 21 19 68
/ \ / \
65 31 32 44
Step 3: We compare 23's two new children, 19 and 68. 19 is less than 68
so we compare 19 with 23. Since 19 is less than 23, we exchange them:
----- 16 -----
/ \
19 19
/ \ / \
26 21 23 68
/ \ / \
65 31 32 44
23 is now a leaf so we are done.
+
/ \
- +
/ \ / \
- 4 8 10
/ \
16 5
This expression tree represents the arithmetic expression:
((16-5) - 4) + (8+10)
which evaluates to 25. An expression tree can be evaluated
by evaluating the left subtree, then the right subtree, and finally
performing the indicated operation on the values returned by evaluating
the left and right subtrees. A leaf evaluates to its number. For example,
in the above expression tree, the + node with the leaves 8 and
10 evaluates to 18 since its left subtree evaluates to 8 and its right
subtree evaluates to 10. Similarly the root + node evaluates to
25 because its left subtree evaluates to 7 and its right subtree to 18.
Your task is to write a function named evaluate that takes a binary tree node as a parameter and returns the integer value of its subtree. If the node is a leaf, the function will return the number associated with the leaf. Otherwise the function will evaluate the left and right subtrees, perform the operation indicated by the node on the results returned by the left and right subtrees, and return this value. A binary tree node has the following declaration:
typedef struct bnode {
int type; // 0 for a leaf, 1 for an operator node
union {
char operator; // can be either '-' or '+'
int number;
};
struct bnode *left;
struct bnode *right;
} BNode;
If the type field indicates that the node is a leaf, then the number
field in the union will be set. If the type field indicates that the
node is an operator node, then the operator field in the union will be set.
#define LEAF 0
int evaluate(BNode *node) {
int left_value;
int right_value;
if (node->type == LEAF)
return node->number;
else {
// node is operator node. evaluate left and right subtrees, then
// combine the result
left_value = evaluate(node->left);
right_value = evaluate(node->right);
if (node->operator == '-')
return left_value - right_value;
else
return left_value + right_value;
}
}