AfanasevGad7

This is a task for our favourite professor
git clone git://git.stellar-nexus.ru/AfanasevGad7
Log | Files | Refs | README

commit 761eeba0b7c121bc8f57706770446634a4a4599b
parent 0ca2f4cc4e6ebcc751ee89eda6083548afe12832
Author: Plat <plat@stellar-nexus.ru>
Date:   Fri,  7 Nov 2025 09:33:27 +0000

Major overhaul to AVL

Diffstat:
MMakefile | 2+-
Aavl.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 190 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ include config.mk -BIN = fib rb +BIN = avl fib rb LIBS = ${wildcard libutil/*.c} OBJS = ${LIBS:.c=.o} diff --git a/avl.c b/avl.c @@ -0,0 +1,189 @@ +#include <iostream> + + +struct Node { + int val; + Node* left; + Node* right; +}; + + + +Node * +init(int val) +{ + Node *n = malloc(sizeof(Node)); + if (n == NULL) + return NULL; + + n->val = val; + n->left = NULL; + n->right = NULL; + + return n; +} + + +Node * +add(Node *root, int val) +{ + if (!root) + return init(val); + + if (val < root->val) + root->left = add(val, root->left); + else if (val > root->val) + root->right = add(val, root->right); + else + return root; + + return balance(root); +} + +int +get_height(Node *root) +{ + int r, l; + + if (!root) + return 0; + + l = get_height(root->left) + 1; + r = get_height(root->right) + 1; + + if (l > r) { + return l; + } + + return r; +} + + +inline int +get_balance_factor(Node *root) +{ + if (!root) + return 0; + + return get_height(root->left) - get_height(root->right); +} + + +Node * +right_turn(Node *root) +{ + if (!root || !root->left) + return root; + + Node *buf = root->left; + root->left = buf->right; + buf->right = root; + return buf; +} + + +Node * +left_turn(Node *root) +{ + if (!root || !root->right) + return root; + + Node *buf = root->right; + root->right = buf->left; + buf->left = root; + return buf; +} + + +Node * +balance(Node *root) +{ + if (!root) + return NULL; + + int bf = get_balance_factor(root); + + + if (bf > 1) { + if (get_balance_factor(root->left) < 0) + root->left = left_turn(root->left); + return right_turn(root); + } + + if (bf < -1) { + if (get_balance_factor(root->right) > 0) + root->right = right_turn(root->right); + return left_turn(root); + } + + return root; +} + + +Node * +search(Node *root, int val) +{ + steps++; + if (root->val == val) return root; + + if (root->val > val) return search(root->left, val); + + return search(root->right, val); +} + +static inline void +usage(void) +{ + eprintf("usage: %s [filename]\n", argv0); +} + +int +main(int argc, char *argv[]) +{ + argv0 = argv[0]; + if (argc > 2) + usage(); + const char *filename; + if (argc == 2) + filename = argv[1]; + else + filename = FILENAME; + + FILE *file; + if (!(file = fopen(filename, "r"))) + eprintf("fopen %s:", filename); + + int arr[TESTNUMBER+1], ch; + char w[64]; + int len = 0, wi = 0; + do { + ch = fgetc(file); + if (!isspace(ch) && ch != EOF) { + w[wi++] = ch; + } else if (wi > 0) { + w[wi] = '\0'; + arr[len++] = estrtonum(w, 0, INT_MAX); + wi = 0; + } + } while (ch != EOF && len <= TESTNUMBER); + efshut(file, filename); + if (len < TESTNUMBER) + eprintf("Array too small\n"); + if (len > TESTNUMBER) + weprintf("Array too big - using only the first %d elements\n", TESTNUMBER); + + Node *root = NULL; + + for (int i = 0; i < TESTNUMBER; ++i) { + root = add(root, arr[i]); + SET_COLOR(root, BLACK); + } + + volatile uintptr_t checksum = 0; /* to avoid optimization */ + clock_t start_time, end_time; + start_time = clock(); + for (int i = 0; i < TESTNUMBER; ++i) + checksum = (uintptr_t)search(root, arr[i]); + end_time = clock(); + printf("%f\n", (double)(end_time-start_time)/CLOCKS_PER_SEC); +}