Fundamentals of Data Structures
Project1
Project Report
2020~2021 秋冬学期 2020 年 9 月 26 日
Categories
CHAPTER 1: INTRODUCTION (6 PTS.)... 3
1.1 BACKGROUNDANDSIGNIFICANCEOFTOPICSELECTION...3
1.2 OURGOALS...3
CHAPTER 2: ALGORITHM SPECIFICATION (12 PTS.)...4
2.1 OVERALLARCHITECTUREDESIGN...4
2.2 ALGORITHMDESIGN...4
CHAPTER 3: TESTING RESULTS (20 PTS.)... 5
Chapter 4: Analysis and Comments (10 pts.)...7
Project1
Chapter 1: Introduction (6 pts.)
1.1 Background and significance of topic selection
Red Black Tree is a self-balancing binary search tree, which is a data structure used in computer science. It is a specialized AVL tree (balanced binary tree), which maintains the balance of the binary search tree through specific operations during insertion and deletion, so as to obtain higher search performance.
Although it is complicated, its worst-case running time is also very good, and it is efficient in practice: it can do search, insert and delete in O (log n) time, where n is in the tree The number of elements.
Property 1. The node is red or black.
Property 2. The root node is black.
Property 3 Every NIL node or empty node is black. (Note that it is not an ordinary leaf node) Nature
Property 4 The two child nodes of each red node are black. (There can be no two consecutive red nodes on all paths from each leaf to the root)
Property 5. All paths from any node to each leaf contain the same number of black nodes.
The definition of the red-black tree path is the path to the leaf node, that is, the NIL node, so that there is no need to consider the left and right child nodes when defining the balance as in the balanced binary tree, and it is uniformly defined as the path length to the NIL node.
1.2 Our goals
Each input file contains several test cases. The first line gives a positive integer K (≤30) which is the total number of cases. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the preorder traversal sequence of the tree. While all the keys in a tree are positive integers, we use negative signs to represent red nodes. All the numbers in a line are separated by a space. The sample input cases correspond to the trees shown in Figure 1, 2 and 3. For each test case, print in a line "Yes" if the given tree is a red- black tree, or "No" if not.
Chapter 2: Algorithm Specification (12 pts.)
2.1 Overall architecture design
2.2 Algorithm design
First, we build a binary tree based on the preorder expression.
We could build a tree preorder through just inserting node one by one. First we insert in node data, if there is a node data, we will insert at left subtree, if there is a
left subtree, we will insert at right subtree.
Then judge whether it is a red-black tree. How to judge a binary tree? According to the nature of the title description, we have to make the following three judgments:
1. Whether the root node is positive,
2. The node is negative, and whether the children of the node are positive (here to determine whether the left and right children of the current node are positive)
3.All paths from any node to the leaf node have the same black node. This problem includes the basic operations of a binary tree: BST tree building, post-order traversal to find tree height, and pre-order traversal.
For property 4, I use recursion, first judge the root, if the root is empty, the return is correct, if the root is negative, judge the left and right values, and if the root is positive, judge the left subtree and the right subtree.
For property 5, judge the height of the left path and the right path. If the node height is the same, the two subtrees will be judged. If they are not the same, it will be wrong.
The function of finding the height, if it is black, then height +1.
Note: we judge null root in the function of finding the height, then No need to write “left == null or right == null” judgment, to write four cases.
pseudo-code
Tree BuildTree(Tree root,int x){
if(root == null)then new a root
if(have a root )then
if( x< root.val) recursive build root.left else recursive build root.right
return root }
bool Pro4(Tree root){
if(root == null)then return true;
if(root is red node) then { if(root.left is red) false if(root.right is red) false }
Recursive judge root.right and root.left property 4 }
int getHeight(Tree root ) { if(root == null)then return 0;
recursive get root.left height recursive get root.right height if(root is black node)
height MAX(leftHeight,rightHeight) +1 else
height MAX(leftHeight,rightHeight) }
bool Pro5(Tree root ) {
if(root == null)then return true;
if(root.left height equal root.right height){
recursive judge root.left’s Property5 and root.right’s property 5 }
Else return flase;
}
void judge(Tree root ) { if (root ==null) then print no if(root is red node) then print no else {
if(root satisify property 4 and 5) print yes
else print no }
}
Main data structures struct Tree {
ElementType Element;
Tree Left;
Tree Right;
}BiTNode;
Chapter 3: Testing Results (20 pts.)
At first, I designed some samples myself and found that they were wrong, because it was not a binary tree, or a red-black tree, and the preorder traversal could not determine a binary tree.
Finally, I add two red-black tree, the fourth tree is correct, the 5th tree is wrong.
test case Actual behavior of my program
7 -2 1 5 -4 -11 8 14 -15 Satisfy the requests
YES
11 -2 1 -7 5 -4 8 14 -15
isn’t a red-black tree,Because node isn’t satisfy property 4
NO
10 -7 5 -6 8 15 -11 17
isn’t a red-black tree,the rightest simple paths from the node to descendant leaves don’t contain the same number of black nodes.
NO
7 -2 1 5 -11 8 14
Try another red-black tree
YES
-2
test property 2 ,root == red node
NO
0
Test empty
NO
3 10 -7 5
Test a tree only have left nodes
NO
7 9
7 -2 1 5 -4 -11 8 14 -15 9
11 -2 1 -7 5 -4 8 14 -15 8
10 -7 5 -6 8 15 -11 17
7
7 -2 1 5 -11 8 14 1
-2 3 10 -7 5 0
Chapter 4: Analysis and Comments (10 pts.)
To process one tree,
time complexities of the algorithms :
worst case:O(N^2), best case: Ω(N logN)
build tree:
log2(1)+log2(2)+...+log2(n)=log2(n!)=O(nlog2n)Pro4 :
O(log2n)recursion times < height of tree O( 2log(n+1)) getHeight: height of tree
Pro5: 2 height of tree* height of tree ( log(n+1))^2 <(nlog2n)
The all time complexities is
O(nlog2n)
space complexities of the algorithms The all space complexities is
Θ(n)Because when a tree with n nodes is built, Θ(n) space is needed to store the tree.
In the process, I meet lots of bugs. I use printf and debug->step in, step over to debug. It really exam my attention and patience. Actually many problem occurs in whether or not if include a Statement block.
The number of red nodes that can be increased is at most as many as the number of black nodes. So the red-black tree guarantees that the longest path does not exceed twice the shortest path, so it is approximately balanced.
Both red-black trees and AVL trees are highly efficient balanced binary trees. The time complexity of adding, deleting, checking and modifying is O(lg(N)). The red- black tree does not pursue complete balance, and the longest path does not exceed twice the shortest path. Relatively speaking, it reduces the requirement of rotation, so the performance will be better than the AVL tree, so there are more red and black trees in actual use.