AfanasevGad7

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

commit a2d666b3cd65783d9b6e7be7312a443b1d8337ca
parent 463fc87d1f300814edd5e6e67cb340205d95a34e
Author: Plat <plat@stellar-nexus.ru>
Date:   Fri,  7 Nov 2025 19:07:35 +0000

Added ntree.cxx

Diffstat:
MMakefile | 6+++++-
Antree.cxx | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 209 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile @@ -1,9 +1,10 @@ include config.mk BIN = avl fib rb +CXX = ntree LIBS = ${wildcard libutil/*.c} OBJS = ${LIBS:.c=.o} -all: ${BIN} config.h +all: ${BIN} ${CXX} config.h config.h: cp config.def.h config.h @@ -12,6 +13,9 @@ ${BIN}: ${BIN:%=%.o} ${OBJS} ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LDFLAGS} strip $@ +${CXX}: ${CXX:%=%.o} ${OBJS} + ${CXX} ${CXXFLAGS} -o $@ $@.cxx ${OBJS} ${LDFLAGS} + %.o: %.c ${CC} ${CFLAGS} -c $< -o $@ diff --git a/ntree.cxx b/ntree.cxx @@ -0,0 +1,204 @@ +#include <iostream> +#include <vector> + +#include "tree.h" + +#include "config.h" + +class NTree { + + struct Node { + int id, data; + std::vector<Node*> children; + }; + + + bool push_node(int id, int data, Node *rt) { + Node *n = new Node; + + n->id = id; + n->data = data; + + rt->children.push_back(n); + + n = rt->children.back(); + + return true; + } + + + Node* find_parent_node(Node *rt, Node *rt_s) { + + if (rt_s->id == 0) return 0; + + if (rt->children.size() == 0) return 0; + + std::vector<Node*> rts; + + for (Node *c : rt->children) { + if (c->id == rt_s->id) return rt; + rts.push_back(this->find_parent_node(c, rt_s)); + } + + for (Node *i : rts) { + if (i) return i; + } + + return 0; + } + + +public: + + Node *root = new Node; + + int last_id = 0; + + + NTree() { + Node *genesis = new Node; + + genesis->id = 0; + genesis->data = 0; + + this->root = genesis; + } + + + bool add(int parent_id, int data, Node *rt) { + + if (rt->id == parent_id) return this->push_node(++this->last_id, data, rt); + + if (rt->children.size() == 0) return false; + + std::vector<bool> r; + + for (auto c : rt->children) { + r.push_back(this->add(parent_id, data, c)); + } + + for (bool a : r) { + if (a) return true; + } + + return false; + }; + + + void parse(Node *rt) { + Node *p = this->find_parent_node(this->root, rt); + std::cout << std::endl << "id: " << rt->id << " data: " << rt->data << " parent id: " << (p ? p->id : (rt->id ? -1 : 0)); + + for (Node *c : rt->children) { + this->parse(c); + } + } + + + Node* search(int id, Node *rt) { + + if (rt->id == id) return rt; + + std::vector<Node*> r; + + for (Node *c : rt->children) { + r.push_back(this->search(id, c)); + } + + for (Node *c : r) { + if (c) return c; + } + + return 0; + } + + + bool remove(int id) { + Node *n = this->search(id, this->root); + Node *n_p = this->find_parent_node(this->root, n); + + for (Node *r : n->children) n_p->children.push_back(r); + + n_p->children.erase(std::find(n_p->children.begin(), n_p->children.end(), n)); + + free(n); + + return true; + + } +}; + +int +main(int argc, char *argv[]) +{ + int cflag = 0, sflag = 0, dflag = 0; + ARGBEGIN { + case 'c': + cflag = 1; + break; + case 's': + sflag = 1; + break; + case 'd': + eprintf("Not implemented\n"); + dflag = 1; + break; + } ARGEND + if (argc > 1 || (cflag + sflag + dflag) < 1) + usage(); + const char *filename; + if (argc == 1) + filename = argv[0]; + 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); + + NTree r; + clock_t start_time, elapsed = 0; + + if (cflag) + start_time = clock(); + for (int i = 0; i < TESTNUMBER; ++i) + r.add(arr[i] % (i+1) - 1, arr[i], r.root); + if (cflag) + elapsed += clock() - start_time; + + volatile uintptr_t checksum = 0; /* to avoid optimization */ + if (sflag) { + start_time = clock(); + for (int i = 0; i < TESTNUMBER; ++i) + checksum = (uintptr_t)r.search(arr[i] % (i+1) - 1, r.root); + elapsed += clock() - start_time; + } + + if (dflag) { + start_time = clock(); + for (int i = 0; i < TESTNUMBER; ++i) + r.remove(arr[i] % (i+1) - 1); + elapsed += clock() - start_time; + } + + printf("%f\n", (double)elapsed/CLOCKS_PER_SEC); +}