Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
79bbc7e
Homework 7 - task 2 (WIP)
ilya-krivtsov Nov 11, 2024
6beb7fd
Added dictionary disposing (hw7 task 2)
ilya-krivtsov Nov 12, 2024
8764824
Fixed adding key-value (hw7 task 2)
ilya-krivtsov Nov 12, 2024
00579ea
Removed unused variable (hw7 task 2)
ilya-krivtsov Nov 12, 2024
58d2a9f
Implemented removing value by key (hw7 task 2)
ilya-krivtsov Nov 12, 2024
bf634ba
Added tests (hw7 task 2)
ilya-krivtsov Nov 12, 2024
bea7662
Add non-NULL value in tests (hw7 task 2)
ilya-krivtsov Nov 12, 2024
5fd6ce0
Added missing return statement (hw7 task 2)
ilya-krivtsov Nov 12, 2024
1162831
Added comments (hw7 task 2)
ilya-krivtsov Nov 12, 2024
2526fd1
Replaced const char * -> char * (hw7 task 2)
ilya-krivtsov Nov 12, 2024
248407a
Added interactive mode (hw7 task 2)
ilya-krivtsov Nov 12, 2024
9bb6ab6
Copy whole string when adding entry (hw7 task 2)
ilya-krivtsov Nov 12, 2024
793c8a1
Input strings are 'const' again (hw7 task 2)
ilya-krivtsov Nov 12, 2024
5a69277
Applied new changes to interactive mode (hw7 task 2)
ilya-krivtsov Nov 12, 2024
100ad86
Attempt make tests run in github actions
ilya-krivtsov Nov 14, 2024
4bbf1c8
Fixed random test (hw7 task 2)
ilya-krivtsov Nov 20, 2024
3c5eaa1
Merge branch 'main' into hw-7-task-2
ilya-krivtsov Nov 25, 2024
41770f8
Merge branch 'main' into hw-7-task-2
ilya-krivtsov Nov 29, 2024
b095c66
Added stdbool.h includes (hw7 task 2)
ilya-krivtsov Dec 10, 2024
0576464
Removed unused string.h include (hw7 task 2)
ilya-krivtsov Dec 10, 2024
abf2c61
Merge branch 'hw-7' into hw-7-task-2
ilya-krivtsov Dec 25, 2024
e44c998
Added task name to README (hw7 task 2)
ilya-krivtsov Dec 25, 2024
6db893c
Merge branch 'main' into hw-7-task-2
ilya-krivtsov Dec 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions homework_7/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ project(homework_7)
set(homeworkName "${PROJECT_NAME}")

add_subdirectory(task_1)
add_subdirectory(task_2)
2 changes: 2 additions & 0 deletions homework_7/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Homework 7

[Task 1. Expression tree](/homework_7/task_1)

[Task 2. Search tree](/homework_7/task_2)
9 changes: 9 additions & 0 deletions homework_7/task_2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
project("${homeworkName}_task_2")

add_library(intStringDictionary intStringDictionary.c)

add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} intStringDictionary)

add_executable(${PROJECT_NAME}_test test.c)
target_link_libraries(${PROJECT_NAME}_test intStringDictionary)
201 changes: 201 additions & 0 deletions homework_7/task_2/intStringDictionary.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#include "intStringDictionary.h"

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node {
int key;
char *value;
struct Node *left;
struct Node *right;
} Node;

typedef struct IntStringDictionary {
Node *root;
} IntStringDictionary;

bool createDictionary(IntStringDictionary **dictionary) {
*dictionary = malloc(sizeof(IntStringDictionary));
if (*dictionary == NULL) {
return false;
}

(*dictionary)->root = NULL;

return true;
}

static bool createNode(Node **node, int key, const char *value) {
*node = malloc(sizeof(Node));
if (*node == NULL) {
return false;
}

(*node)->key = key;

char *valueCopy = strdup(value);
if (valueCopy == NULL) {
return false;
}
(*node)->value = valueCopy;

(*node)->left = NULL;
(*node)->right = NULL;

return true;
}

static bool addAfterNode(Node *node, int key, const char *value) {
Node *parent = NULL;
Node *child = node;
while (child != NULL) {
parent = child;
if (key > parent->key) {
child = parent->right;
} else if (key < parent->key) {
child = parent->left;
} else {
free(parent->value);
char *valueCopy = strdup(value);
if (valueCopy == NULL) {
return false;
}
parent->value = valueCopy;
return true;
}
}

if (parent == NULL) {
return false;
}

Node **childPointer = key > parent->key ? &parent->right: &parent->left;

return createNode(childPointer, key, value);
}

bool addToDictionary(IntStringDictionary *dictionary, int key, const char *value) {
if (dictionary->root == NULL) {
return createNode(&dictionary->root, key, value);
}

return addAfterNode(dictionary->root, key, value);
}

Node *getNode(Node *node, int key) {
while (true) {
if (node == NULL) {
return NULL;
}

if (key < node->key) {
node = node->left;
} else if (key > node->key) {
node = node->right;
} else {
break;
}
}

return node;
}

char *getValue(IntStringDictionary *dictionary, int key) {
Node *node = getNode(dictionary->root, key);

return node == NULL ? NULL : node->value;
}

bool containsKey(IntStringDictionary *dictionary, int key) {
Node *node = getNode(dictionary->root, key);

return node != NULL;
}

// returns rightmost child of given node, or node itself if right is NULL
Node *getRightmost(Node *node) {
while (node->right != NULL) {
node = node->right;
}
return node;
}

bool removeFromDictionary(IntStringDictionary *dictionary, int key) {
Node *node = dictionary->root;
Node *previous = NULL;
while (true) {
if (node == NULL) {
return false;
}

if (key < node->key) {
previous = node;
node = node->left;
} else if (key > node->key) {
previous = node;
node = node->right;
} else {
break;
}
}

if (node == dictionary->root) {
if (node->left == NULL) {
dictionary->root = node->right;
free(node);
return true;
}

if (node->right == NULL) {
dictionary->root = node->left;
free(node);
return true;
}

Node *rightmostInLeft = getRightmost(node->left);
rightmostInLeft->right = node->right;
dictionary->root = node->left;

free(node);

return true;
}

Node **setNewNodeTo = key < previous->key ? &previous->left : &previous->right;

if (node->left == NULL) {
*setNewNodeTo = node->right;
free(node);
return true;
}

if (node->right == NULL) {
*setNewNodeTo = node->left;
free(node);
return true;
}

Node *rightmostInLeft = getRightmost(node->left);
rightmostInLeft->right = node->right;
*setNewNodeTo = node->left;
free(node);
return true;
}

void disposeNode(Node *node) {
if (node == NULL) {
return;
}

disposeNode(node->left);
disposeNode(node->right);

free(node->value);
free(node);
}

void disposeDictionary(IntStringDictionary *dictionary) {
disposeNode(dictionary->root);
free(dictionary);
}
40 changes: 40 additions & 0 deletions homework_7/task_2/intStringDictionary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <stdbool.h>

/// @brief Dictionary of `int` keys associated with `char *` values
typedef struct IntStringDictionary IntStringDictionary;

/// @brief Creates new dictionary
/// @param dictionary Pointer to write new dictionary to
/// @return `true` if created successfully, `false` otherwise (allocation failed)
bool createDictionary(IntStringDictionary **dictionary);

/// @brief Adds key and associated with it value to dictionary
/// @param dictionary Dictionary to add key and value to
/// @param key Key to add
/// @param value Value to add
/// @return `true` if added successfully, `false` otherwise (allocation failed)
bool addToDictionary(IntStringDictionary *dictionary, int key, const char *value);

/// @brief Gets value corresponding to given key
/// @param dictionary Dictionary to get value from
/// @param key Key associated with value
/// @return String associated with key, or `NULL` if value was not found
char *getValue(IntStringDictionary *dictionary, int key);

/// @brief Checks if dictionary contains given key
/// @param dictionary Dictionary to check
/// @param key Key to check
/// @return `true` if key exists in dictionary, `false` otherwise
bool containsKey(IntStringDictionary *dictionary, int key);

/// @brief Removes value from dictionary using given key
/// @param dictionary Dictionary to remove value from
/// @param key Key associated with value to be removed
/// @return `true` if removed successfully, `false` otherwise (key does not exist in dictionary)
bool removeFromDictionary(IntStringDictionary *dictionary, int key);

/// @brief Disposes dictionary and all of its entries
/// @param dictionary Dictionary to dispose
void disposeDictionary(IntStringDictionary *dictionary);
Loading