icp/oer/courses/c-advanced/sections/01-introduction/06-tree/solution.c

177 lines
3.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int Value;
struct node *Left;
struct node *Right;
}node;
node *alloc_node(int Value, node *Left, node *Right)
{
node *NewNode = malloc(sizeof(node));
NewNode->Value = Value;
NewNode->Left = Left;
NewNode->Right = Right;
return NewNode;
}
// inserts into the right place in the tree
void tree_insert(node **Root, int Value)
{
// TODO: implement this
if(*Root)
{
node *Node = *Root;
if(Value <= Node->Value)
{
tree_insert(&Node->Left, Value);
}
else
{
tree_insert(&Node->Right, Value);
}
}
else
{
*Root = alloc_node(Value, 0, 0);
}
}
// finds the node with the given value.
// if it doesn't find one return null
node *tree_find(node *Root, int Value)
{
// TODO: implement this
node *Node = Root;
if(Node)
{
if(Value < Node->Value)
{
tree_find(Node->Left, Value);
}
else if(Value > Node->Value)
{
tree_find(Node->Right, Value);
}
else
{
return Node;
}
}
return 0;
}
// deletes the node with the value while remaining sorted
void tree_delete(node **Root, node *Parent, int Value)
{
node *Node = *Root;
if(Node)
{
if(Value < Node->Value)
{
tree_delete(&Node->Left, Node, Value);
}
else if(Value > Node->Value)
{
tree_delete(&Node->Right, Node, Value);
}
else // Found node
{
node *NodeToDelete = Node;
if(NodeToDelete->Left && NodeToDelete->Right)
{
node *RightSubTree = NodeToDelete->Right;
if(RightSubTree)
{
node *LowestNode = RightSubTree->Left;
node *Prev;
while(LowestNode->Left)
{
Prev = LowestNode;
LowestNode = LowestNode->Left;
}
NodeToDelete->Value = LowestNode->Value;
Prev->Left = 0;
tree_delete(&LowestNode, Prev, LowestNode->Value);
}
}
else if(NodeToDelete->Left)
{
if(Parent)
Parent->Left = NodeToDelete->Left;
free(NodeToDelete);
}
else if(NodeToDelete->Right)
{
if(Parent)
Parent->Left = NodeToDelete->Right;
free(NodeToDelete);
}
else
{
if(Parent)
Parent->Left = 0;
free(NodeToDelete);
}
}
}
// TODO: implement this
}
// prints every member in a sorted way
void tree_print_sorted(node *Root)
{
// TODO: implement this
node *Node = Root;
if(Node)
{
node *Left = Node->Left;
tree_print_sorted(Left);
printf("%d ", Node->Value);
node *Right = Node->Right;
tree_print_sorted(Right);
}
}
int main(int argc, char **argv)
{
node *Root;
int Numbers[10] = {9, 128, 3, 1, 42, 9001, 7, 500, 6, 10};
// NOTE: filling the tree with numbers
for(int i = 0 ; i < 10; i++)
{
tree_insert(&Root, Numbers[i]);
}
node *Nine = tree_find(Root, 9);
int FoundNine = 0;
if(Nine)
{
FoundNine = 1;
node *Left = Nine->Left;
node *Right = Nine->Right;
printf("Found %d with direct child %d and %d\n", Nine->Value, (Left)? Left->Value: 0, (Right)? Right->Value : 0);
}
tree_delete(&Root, 0, 9);
Nine = tree_find(Root, 9);
if(Nine)
{
printf("Failed to delete %d\n", Nine->Value);
}
else
{
if(FoundNine)
printf("Succesfully deleted 9\n");
}
tree_print_sorted(Root);
printf("\n");
}