haas/fall2026/data/projects/dlt0.md
... ...
@@ -0,0 +1,195 @@
1
+# PROJECT: DOUBLY LINKED TREES (dlt0)
2
+
3
+## OBJECTIVE
4
+
5
+Re-using our doubly-linked node structure to construct an ordered
6
+binary search tree.
7
+
8
+## TASK
9
+
10
+By the deadline, please do the following:
11
+
12
+ * create a `Tree` management struct, containing a `root` `Node`
13
+ pointer and a `height` integer
14
+ * `root` points to the node at the top of the tree (NULL if empty)
15
+ * `height` tracks the maximum height of the tree (an empty tree has
16
+ a height of 0)
17
+ * implement the following Tree functions (each takes a `Tree *` as
18
+ its first parameter, and returns the updated `Tree *`):
19
+ * `Tree *mktree ();`
20
+ * `Tree *cleartree (Tree *);`
21
+ * `Tree *rmtree (Tree *);`
22
+ * `Tree *addnode (Tree *, Node *);`
23
+ * `Tree *grabnode (Tree *, Node **);`
24
+ * `Tree *traverse (Tree *, List *, int);`
25
+ * `Tree *findnode (Tree *, Node **, int);`
26
+ * test your tree implementation
27
+
28
+## BACKGROUND
29
+
30
+A binary search tree is an ordered, hierarchical data structure: each
31
+node has up to two children, and the position of a node is determined
32
+by its value relative to the nodes already in the tree.
33
+
34
+We will not be creating a new node type. The `Node` you built for your
35
+doubly-linked list already has two pointers, and we will simply give
36
+them new meaning:
37
+
38
+ * `prev` will point to the **left** child
39
+ * `next` will point to the **right** child
40
+
41
+The ordering rule is as follows:
42
+
43
+ * values **less than or equal** to a node's value go into its left
44
+ subtree
45
+ * values **greater than** a node's value go into its right subtree
46
+
47
+Note that there is no parent pointer: your `Node` struct does not need
48
+to (and should not) change for this project. Functions that need to
49
+know about a node's parent will need to track it as they descend.
50
+
51
+You are expected to continue making use of your existing node
52
+functions (`mknode()`, `rmnode()`) wherever they apply.
53
+
54
+### TREE STRUCT
55
+
56
+Much like `List` and the others before it, `Tree` is a management layer:
57
+it gives us a reliable point of access to the tree (`root`), and a place
58
+to keep track of information about the tree as a whole (`height`).
59
+
60
+### MKTREE()
61
+
62
+Like `mklist()`, except it focuses on creating a new, empty Tree
63
+instance. Allocate memory and do any error checking, ensuring `root` is
64
+set to `NULL` and `height` to 0.
65
+
66
+On error, `mktree()` should return `NULL`.
67
+
68
+### CLEARTREE()
69
+
70
+The purpose of `cleartree()` is to effectively and reliably empty a
71
+tree: every node in the tree is removed and deallocated (this will
72
+require visiting every node, so think carefully about the order in which
73
+you do it: don't free a node before you are done with its children).
74
+
75
+An empty tree is returned, or `NULL` on some sort of error state.
76
+
77
+### RMTREE()
78
+
79
+The purpose of `rmtree()` is to empty and deallocate a given tree,
80
+returning a `NULL` value at the end.
81
+
82
+You can pass a populated tree to `rmtree()`: it is `rmtree()`'s job to
83
+call other routines to clear out the tree before deallocating the tree
84
+pointer in question.
85
+
86
+### ADDNODE()
87
+
88
+Places the provided node into its proper position in the tree, according
89
+to the ordering rule (value <= goes to the left subtree, otherwise
90
+right).
91
+
92
+The parameters are as follows:
93
+
94
+ * pointer to the tree
95
+ * pointer to the node you'd like to add to the tree
96
+
97
+A pointer to the tree is returned.
98
+
99
+Be sure to handle the case of an empty tree (the new node becomes the
100
+`root`), and to keep `height` up to date as the tree grows.
101
+
102
+You should check to make sure the involved things are not NULL (as a
103
+segmentation fault would occur otherwise).
104
+
105
+### GRABNODE()
106
+
107
+To get a node out of the tree, we `grabnode()` it. This function will
108
+isolate a node from the tree, maintaining the ordering of the remaining
109
+nodes.
110
+
111
+The parameters are as follows:
112
+
113
+ * pointer to the tree
114
+ * double pointer to the node you'd like to grab
115
+
116
+A pointer to the tree is returned, and the double pointer will reference
117
+the now-isolated node (its `prev` and `next` pointers should be NULL).
118
+
119
+There are three scenarios you will need to account for:
120
+
121
+ * the node has no children (a leaf): simply remove it
122
+ * the node has one child: that child takes its place
123
+ * the node has two children: the **greatest value in its left
124
+ subtree** is promoted to take its place
125
+
126
+Be mindful of grabbing the `root` node (the tree's `root` pointer must be
127
+updated), and be sure to keep `height` accurate afterwards.
128
+
129
+### TRAVERSE()
130
+
131
+Recursively traverses the tree, building a **list** of the nodes in the
132
+order visited.
133
+
134
+The parameters are as follows:
135
+
136
+ * pointer to the tree
137
+ * pointer to the list the results will be placed into
138
+ * integer indicating the traversal order:
139
+ * inorder (left, node, right)
140
+ * preorder (node, left, right)
141
+ * postorder (left, right, node)
142
+
143
+You will want to define meaningful names for the three traversal orders
144
+(constants, `#define`, or `enum`) instead of passing around bare
145
+numbers.
146
+
147
+A pointer to the tree is returned.
148
+
149
+Because the nodes in the tree are using their `prev` and `next` pointers
150
+for tree connections, the list must be populated with **new** nodes
151
+(created with `mknode()`) containing copies of each value. The tree
152
+itself must remain unchanged by a traversal. The caller is responsible
153
+for the resulting list.
154
+
155
+Hint: an inorder traversal of a binary search tree will yield its values
156
+in sorted order.
157
+
158
+### FINDNODE()
159
+
160
+Locates the first match of a value within the tree.
161
+
162
+The parameters are as follows:
163
+
164
+ * pointer to the tree
165
+ * double pointer which will be set to the node found
166
+ * the integer value being sought
167
+
168
+A pointer to the tree is returned. If the value is not found, the node
169
+double pointer is set to `NULL`. The tree is not modified, and the
170
+located node is **not** removed from the tree.
171
+
172
+Remember that the tree's ordering rule means you do not need to look at
173
+every node: use it to decide which way to descend.
174
+
175
+## SUBMISSION
176
+
177
+```
178
+208:dlt0:final tally of results (208/208)
179
+*:dlt0:create tree struct [13/13]
180
+*:dlt0:create and test mktree function [13/13]
181
+*:dlt0:create and test cleartree function [13/13]
182
+*:dlt0:create and test rmtree function [13/13]
183
+*:dlt0:create and test addnode function [26/26]
184
+*:dlt0:create and test grabnode function [26/26]
185
+*:dlt0:create and test traverse function [26/26]
186
+*:dlt0:create and test findnode function [26/26]
187
+*:dlt0:tree height is accurately maintained [26/26]
188
+*:dlt0:code is well commented, organized, functional [26/26]
189
+```
190
+
191
+Additionally:
192
+ * Solutions not abiding by spirit of project will be subject to a 25% overall deduction
193
+ * Solutions not utilizing descriptive why and how comments will be subject to a 25% overall deduction
194
+ * Solutions not utilizing indentation to promote scope and clarity will be subject to a 25% overall deduction
195
+ * Solutions not organized and easy to read (assume a terminal at least 90 characters wide, 40 characters tall) are subject to a 25% overall deduction