Compare commits
No commits in common. "2a8c600c22cdfea5abe4aaa41ce481d62bf523b0" and "12d5c261245a3d6b8687a8cb87a54a5cb7e0c643" have entirely different histories.
2a8c600c22
...
12d5c26124
8 changed files with 185 additions and 99 deletions
4
Makefile
4
Makefile
|
@ -15,7 +15,7 @@ SRCS := $(wildcard $(SRC_DIR)/*.c)
|
||||||
OBJS := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
|
OBJS := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
|
||||||
|
|
||||||
# Target executable
|
# Target executable
|
||||||
TARGET := $(BUILD_DIR)/CTree
|
TARGET := CTree
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
@ -38,4 +38,4 @@ clean:
|
||||||
rm -rf $(BUILD_DIR) $(TARGET)
|
rm -rf $(BUILD_DIR) $(TARGET)
|
||||||
|
|
||||||
# Mark rules as phony
|
# Mark rules as phony
|
||||||
.PHONY: all run clean
|
.PHONY: all run clean
|
7
src/fib.c
Normal file
7
src/fib.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include "fib.h"
|
||||||
|
|
||||||
|
int fib(int n) {
|
||||||
|
if (n < 2)
|
||||||
|
return n;
|
||||||
|
return fib(n - 1) + fib(n - 2);
|
||||||
|
}
|
3
src/fib.h
Normal file
3
src/fib.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
int fib(int n);
|
8
src/greet.c
Normal file
8
src/greet.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "greet.h"
|
||||||
|
#include "fib.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void greet(const char *name) {
|
||||||
|
printf("Hello %s!\n", name);
|
||||||
|
printf("Fibonacci of 10 is %d\n", fib(10));
|
||||||
|
}
|
3
src/greet.h
Normal file
3
src/greet.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void greet(const char *name);
|
164
src/main.c
164
src/main.c
|
@ -1,7 +1,161 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "tree.h"
|
#include "greet.h"
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
int data;
|
||||||
|
struct Node *left, *right;
|
||||||
|
};
|
||||||
|
typedef struct Node Node;
|
||||||
|
|
||||||
|
struct Tree {
|
||||||
|
Node *root;
|
||||||
|
};
|
||||||
|
typedef struct Tree Tree;
|
||||||
|
|
||||||
|
int tree_insert(Tree *tree, int data) {
|
||||||
|
Node *node = malloc(sizeof(Node));
|
||||||
|
node->data = data;
|
||||||
|
node->left = NULL;
|
||||||
|
node->right = NULL;
|
||||||
|
|
||||||
|
if (tree->root == NULL) {
|
||||||
|
tree->root = node;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *current = tree->root;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (data < current->data) {
|
||||||
|
if (current->left == NULL) {
|
||||||
|
current->left = node;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
current = current->left;
|
||||||
|
} else {
|
||||||
|
if (current->right == NULL) {
|
||||||
|
current->right = node;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
current = current->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tree_remove(Tree *tree, int data) {
|
||||||
|
if (tree->root == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *current = tree->root;
|
||||||
|
Node *parent = NULL;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (data < current->data) {
|
||||||
|
parent = current;
|
||||||
|
current = current->left;
|
||||||
|
} else if (data > current->data) {
|
||||||
|
parent = current;
|
||||||
|
current = current->right;
|
||||||
|
} else {
|
||||||
|
if (current->left == NULL && current->right == NULL) {
|
||||||
|
if (parent == NULL) {
|
||||||
|
tree->root = NULL;
|
||||||
|
} else if (parent->left == current) {
|
||||||
|
parent->left = NULL;
|
||||||
|
} else {
|
||||||
|
parent->right = NULL;
|
||||||
|
}
|
||||||
|
free(current);
|
||||||
|
return 0;
|
||||||
|
} else if (current->left == NULL) {
|
||||||
|
if (parent == NULL) {
|
||||||
|
tree->root = current->right;
|
||||||
|
} else if (parent->left == current) {
|
||||||
|
parent->left = current->right;
|
||||||
|
} else {
|
||||||
|
parent->right = current->right;
|
||||||
|
}
|
||||||
|
free(current);
|
||||||
|
return 0;
|
||||||
|
} else if (current->right == NULL) {
|
||||||
|
if (parent == NULL) {
|
||||||
|
tree->root = current->left;
|
||||||
|
} else if (parent->left == current) {
|
||||||
|
parent->left = current->left;
|
||||||
|
} else {
|
||||||
|
parent->right = current->left;
|
||||||
|
}
|
||||||
|
free(current);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
Node *successor = current->right;
|
||||||
|
Node *successor_parent = current;
|
||||||
|
while (successor->left != NULL) {
|
||||||
|
successor_parent = successor;
|
||||||
|
successor = successor->left;
|
||||||
|
}
|
||||||
|
current->data = successor->data;
|
||||||
|
if (successor_parent->left == successor) {
|
||||||
|
successor_parent->left = successor->right;
|
||||||
|
} else {
|
||||||
|
successor_parent->right = successor->right;
|
||||||
|
}
|
||||||
|
free(successor);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tree_clear(Tree *tree) {
|
||||||
|
if (tree->root == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *current = tree->root;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (current->left != NULL) {
|
||||||
|
current = current->left;
|
||||||
|
} else if (current->right != NULL) {
|
||||||
|
current = current->right;
|
||||||
|
} else {
|
||||||
|
Node *parent = current;
|
||||||
|
current = NULL;
|
||||||
|
if (parent == tree->root) {
|
||||||
|
tree->root = NULL;
|
||||||
|
} else if (parent->left != NULL) {
|
||||||
|
parent->left = NULL;
|
||||||
|
} else {
|
||||||
|
parent->right = NULL;
|
||||||
|
}
|
||||||
|
free(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tree_size(Tree *tree) {
|
||||||
|
if (tree->root == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
Node *current = tree->root;
|
||||||
|
while (current != NULL) {
|
||||||
|
size++;
|
||||||
|
if (current->left != NULL) {
|
||||||
|
current = current->left;
|
||||||
|
} else if (current->right != NULL) {
|
||||||
|
current = current->right;
|
||||||
|
} else {
|
||||||
|
current = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
Tree tree = {NULL};
|
Tree tree = {NULL};
|
||||||
|
@ -10,5 +164,11 @@ int main(void) {
|
||||||
tree_insert(&tree, 2);
|
tree_insert(&tree, 2);
|
||||||
tree_insert(&tree, 3);
|
tree_insert(&tree, 3);
|
||||||
printf("Tree size: %d\n", tree_size(&tree));
|
printf("Tree size: %d\n", tree_size(&tree));
|
||||||
|
tree_remove(&tree, 2);
|
||||||
|
printf("Tree size: %d\n", tree_size(&tree));
|
||||||
|
tree_clear(&tree);
|
||||||
|
printf("Tree size: %d\n", tree_size(&tree));
|
||||||
|
|
||||||
|
greet("Template");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
73
src/tree.c
73
src/tree.c
|
@ -1,73 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "tree.h"
|
|
||||||
|
|
||||||
int tree_insert(Tree *tree, int data) {
|
|
||||||
Node *new_node = malloc(sizeof(Node));
|
|
||||||
new_node->data = data;
|
|
||||||
new_node->left = NULL;
|
|
||||||
new_node->right = NULL;
|
|
||||||
|
|
||||||
// If the tree is empty
|
|
||||||
if (tree->root == NULL) {
|
|
||||||
tree->root = new_node;
|
|
||||||
return 0; // Early return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the tree is non-empty
|
|
||||||
Node *cursor = tree->root;
|
|
||||||
|
|
||||||
// An iterative (non-recursive approach) to tree insertion
|
|
||||||
// While we look for a place to put our new node
|
|
||||||
while(1) {
|
|
||||||
// If larger than data
|
|
||||||
if(new_node->data > cursor->data) {
|
|
||||||
// If there is a child to the right
|
|
||||||
if(cursor->right != NULL) cursor = cursor->right;
|
|
||||||
else {
|
|
||||||
cursor->right = new_node; // Put our node here
|
|
||||||
break; // Break the outer while loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If less-or-equal than our data
|
|
||||||
if(new_node->data <= cursor->data) {
|
|
||||||
// If there is a child to the left
|
|
||||||
if(cursor->left != NULL) cursor = cursor->left;
|
|
||||||
else {
|
|
||||||
cursor->left = new_node; // Put our node here
|
|
||||||
break; // Break the outer while loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int tree_remove(Tree *tree, int data) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tree_clear(Tree *tree) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tree_size(Tree *tree) {
|
|
||||||
if (tree->root == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
Node *current = tree->root;
|
|
||||||
while (current != NULL) {
|
|
||||||
size++;
|
|
||||||
if (current->left != NULL) {
|
|
||||||
current = current->left;
|
|
||||||
} else if (current->right != NULL) {
|
|
||||||
current = current->right;
|
|
||||||
} else {
|
|
||||||
current = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
22
src/tree.h
22
src/tree.h
|
@ -1,22 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// A regular node with a left and right branch
|
|
||||||
struct Node {
|
|
||||||
int data;
|
|
||||||
struct Node *left, *right;
|
|
||||||
};
|
|
||||||
typedef struct Node Node;
|
|
||||||
|
|
||||||
// Represents a tree with a root node
|
|
||||||
struct Tree {
|
|
||||||
Node *root;
|
|
||||||
};
|
|
||||||
typedef struct Tree Tree;
|
|
||||||
|
|
||||||
int tree_insert(Tree *tree, int data);
|
|
||||||
int tree_remove(Tree *tree, int data);
|
|
||||||
int tree_clear(Tree *tree);
|
|
||||||
int tree_size(Tree *tree);
|
|
Loading…
Reference in a new issue