Refactoring AVL tree to accept duplicate values so that it can be actually used as a priority queue.

This commit is contained in:
secXsQuared 2016-05-20 12:07:11 -07:00
parent 3bfa585967
commit cd5d08fa1d
5 changed files with 132 additions and 102 deletions

View File

@ -1,6 +1,6 @@
#include "linked_list.h"
static void SAPI _init_linked_list_node(linked_list_node_t *node)
static void SAPI _init_linked_list_node(linked_list_entry_t *node)
{
if (node != NULL)
{
@ -10,12 +10,12 @@ static void SAPI _init_linked_list_node(linked_list_node_t *node)
return;
}
static void SAPI _append_node(linked_list_node_t *target, linked_list_node_t *node)
static void SAPI _append_node(linked_list_entry_t *target, linked_list_entry_t *node)
{
if(target == NULL || node == NULL)
return;
linked_list_node_t* next = target->next;
linked_list_entry_t* next = target->next;
// update the next node
if(next != NULL)
{
@ -33,12 +33,12 @@ static void SAPI _append_node(linked_list_node_t *target, linked_list_node_t *no
}
// link target with node, suppose target is in the current list
static void SAPI _prepend_node(linked_list_node_t *target, linked_list_node_t *node)
static void SAPI _prepend_node(linked_list_entry_t *target, linked_list_entry_t *node)
{
if(target == NULL || node == NULL)
return;
linked_list_node_t* prev = target->prev;
linked_list_entry_t* prev = target->prev;
// update the prev node
if(prev != NULL)
{
@ -55,7 +55,7 @@ static void SAPI _prepend_node(linked_list_node_t *target, linked_list_node_t *n
return;
}
static void SAPI _unlink_node(linked_list_node_t* node)
static void SAPI _unlink_node(linked_list_entry_t* node)
{
if(node == NULL)
return;
@ -91,8 +91,8 @@ int32_t SAPI linked_list_size(linked_list_t *list)
return 0;
int32_t size = 1;
linked_list_node_t *cur_node = list->head;
linked_list_node_t *tail = list->tail;
linked_list_entry_t *cur_node = list->head;
linked_list_entry_t *tail = list->tail;
while ((cur_node != tail) && ((cur_node = cur_node->next) != NULL))
{
size++;
@ -100,7 +100,7 @@ int32_t SAPI linked_list_size(linked_list_t *list)
return size;
}
void SAPI linked_list_push_front(linked_list_t *list, linked_list_node_t *node)
void SAPI linked_list_push_front(linked_list_t *list, linked_list_entry_t *node)
{
if (list == NULL || node == NULL)
return;
@ -112,7 +112,7 @@ void SAPI linked_list_push_front(linked_list_t *list, linked_list_node_t *node)
return;
}
void SAPI linked_list_push_back(linked_list_t *list, linked_list_node_t *node)
void SAPI linked_list_push_back(linked_list_t *list, linked_list_entry_t *node)
{
if (list == NULL || node == NULL)
return;
@ -124,14 +124,14 @@ void SAPI linked_list_push_back(linked_list_t *list, linked_list_node_t *node)
return;
}
linked_list_node_t *SAPI linked_list_pop_front(linked_list_t *list)
linked_list_entry_t *SAPI linked_list_pop_front(linked_list_t *list)
{
if (list == NULL)
return NULL;
return linked_list_remove_ref(list, list->head);
}
linked_list_node_t *SAPI linked_list_pop_back(linked_list_t *list)
linked_list_entry_t *SAPI linked_list_pop_back(linked_list_t *list)
{
if (list == NULL)
return NULL;
@ -140,7 +140,7 @@ linked_list_node_t *SAPI linked_list_pop_back(linked_list_t *list)
}
void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_node_t *prev_node, linked_list_node_t *node)
void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_entry_t *prev_node, linked_list_entry_t *node)
{
if (list == NULL || node == NULL)
return;
@ -175,11 +175,11 @@ void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_node_t *prev_n
}
}
void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list_node_t *node)
void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list_entry_t *node)
{
if (list == NULL || index < 0 || node == NULL)
return;
linked_list_node_t *prev_node = linked_list_get(list, index - 1);
linked_list_entry_t *prev_node = linked_list_get(list, index - 1);
_init_linked_list_node(node);
if (prev_node == NULL)
@ -197,11 +197,11 @@ void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list
return;
}
linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t index)
linked_list_entry_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t index)
{
if (list == NULL || index < 0)
return NULL;
linked_list_node_t *cur_node = linked_list_get(list, index);
linked_list_entry_t *cur_node = linked_list_get(list, index);
if (cur_node == NULL)
return NULL;
@ -209,7 +209,7 @@ linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t ind
return linked_list_remove_ref(list, cur_node);
}
linked_list_node_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list_node_t *node)
linked_list_entry_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list_entry_t *node)
{
if (list == NULL || node == NULL)
return NULL;
@ -231,16 +231,16 @@ linked_list_node_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list
return node;
}
linked_list_node_t *SAPI linked_list_get(linked_list_t *list, int32_t index)
linked_list_entry_t *SAPI linked_list_get(linked_list_t *list, int32_t index)
{
if (list == NULL || index < 0 || list->head == NULL)
return NULL;
linked_list_node_t *cur_node = list->head;
linked_list_entry_t *cur_node = list->head;
while (index-- && (cur_node = cur_node->next) != NULL);
return cur_node;
}
linked_list_node_t *SAPI linked_list_next(linked_list_node_t *node)
linked_list_entry_t *SAPI linked_list_next(linked_list_entry_t *node)
{
if (node != NULL)
{
@ -249,7 +249,7 @@ linked_list_node_t *SAPI linked_list_next(linked_list_node_t *node)
return node;
}
linked_list_node_t *SAPI linked_list_prev(linked_list_node_t *node)
linked_list_entry_t *SAPI linked_list_prev(linked_list_entry_t *node)
{
if (node != NULL)
{
@ -258,9 +258,9 @@ linked_list_node_t *SAPI linked_list_prev(linked_list_node_t *node)
return node;
}
linked_list_node_t *SAPI linked_list_first(linked_list_t *list)
linked_list_entry_t *SAPI linked_list_first(linked_list_t *list)
{
linked_list_node_t *result = NULL;
linked_list_entry_t *result = NULL;
if (list != NULL)
{
result = list->head;
@ -268,9 +268,9 @@ linked_list_node_t *SAPI linked_list_first(linked_list_t *list)
return result;
}
linked_list_node_t *SAPI linked_list_last(linked_list_t *list)
linked_list_entry_t *SAPI linked_list_last(linked_list_t *list)
{
linked_list_node_t *result = NULL;
linked_list_entry_t *result = NULL;
if (list != NULL)
{
result = list->tail;
@ -278,12 +278,12 @@ linked_list_node_t *SAPI linked_list_last(linked_list_t *list)
return result;
}
int32_t SAPI linked_list_search(linked_list_t *list, linked_list_node_t *target, bool (*equals)(linked_list_node_t *, linked_list_node_t *))
int32_t SAPI linked_list_search(linked_list_t *list, linked_list_entry_t *target, bool (*equals)(linked_list_entry_t *, linked_list_entry_t *))
{
if(list == NULL || target == NULL)
return -1;
int32_t result = 0;
linked_list_node_t* node = linked_list_first(list);
linked_list_entry_t* node = linked_list_first(list);
while(node != NULL)
{
if(equals !=NULL)

View File

@ -3,48 +3,48 @@
#include "../../../sys/kdef.h"
typedef struct _linked_list_node_t
typedef struct _linked_list_entry_t
{
struct _linked_list_node_t *prev;
struct _linked_list_node_t *next;
} linked_list_node_t;
struct _linked_list_entry_t *prev;
struct _linked_list_entry_t *next;
} linked_list_entry_t;
typedef struct _linked_list_t
{
linked_list_node_t *head;
linked_list_node_t *tail;
linked_list_entry_t *head;
linked_list_entry_t *tail;
} linked_list_t;
void SAPI linked_list_init(linked_list_t *list);
int SAPI linked_list_size(linked_list_t *list);
void SAPI linked_list_push_front(linked_list_t *list, linked_list_node_t *node);
void SAPI linked_list_push_front(linked_list_t *list, linked_list_entry_t *node);
void SAPI linked_list_push_back(linked_list_t *list, linked_list_node_t *node);
void SAPI linked_list_push_back(linked_list_t *list, linked_list_entry_t *node);
linked_list_node_t *SAPI linked_list_pop_front(linked_list_t *list);
linked_list_entry_t *SAPI linked_list_pop_front(linked_list_t *list);
linked_list_node_t *SAPI linked_list_pop_back(linked_list_t *list);
linked_list_entry_t *SAPI linked_list_pop_back(linked_list_t *list);
void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list_node_t *node);
void SAPI linked_list_insert_idx(linked_list_t *list, int32_t index, linked_list_entry_t *node);
void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_node_t *prev_node, linked_list_node_t *node);
void SAPI linked_list_insert_ref(linked_list_t *list, linked_list_entry_t *prev_node, linked_list_entry_t *node);
linked_list_node_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t index);
linked_list_entry_t *SAPI linked_list_remove_idx(linked_list_t *list, int32_t index);
linked_list_node_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list_node_t *node);
linked_list_entry_t *SAPI linked_list_remove_ref(linked_list_t *list, linked_list_entry_t *node);
linked_list_node_t *SAPI linked_list_get(linked_list_t *list, int32_t index);
linked_list_entry_t *SAPI linked_list_get(linked_list_t *list, int32_t index);
linked_list_node_t *SAPI linked_list_next(linked_list_node_t *node);
linked_list_entry_t *SAPI linked_list_next(linked_list_entry_t *node);
linked_list_node_t *SAPI linked_list_prev(linked_list_node_t *node);
linked_list_entry_t *SAPI linked_list_prev(linked_list_entry_t *node);
linked_list_node_t *SAPI linked_list_first(linked_list_t *list);
linked_list_entry_t *SAPI linked_list_first(linked_list_t *list);
linked_list_node_t *SAPI linked_list_last(linked_list_t *list);
linked_list_entry_t *SAPI linked_list_last(linked_list_t *list);
int32_t SAPI linked_list_search(linked_list_t *list, linked_list_node_t* target, bool (*equals)(linked_list_node_t*, linked_list_node_t*));
int32_t SAPI linked_list_search(linked_list_t *list, linked_list_entry_t* target, bool (*equals)(linked_list_entry_t*, linked_list_entry_t*));
#endif

View File

@ -1,21 +1,21 @@
#include "../../../sys/kdef.h"
#include "avl_tree.h"
static int SAPI _avl_tree_node_get_height(avl_tree_node_t *node)
static int SAPI _avl_tree_node_get_height(avl_tree_entry_t *node)
{
return node == NULL ? -1 : node->height;
}
static int SAPI _avl_tree_node_get_balance_factor(avl_tree_node_t *node)
static int SAPI _avl_tree_node_get_balance_factor(avl_tree_entry_t *node)
{
if (node == NULL)
return 0;
return _avl_tree_node_get_height(node->left) - _avl_tree_node_get_height(node->right);
}
static avl_tree_node_t *SAPI _avl_tree_node_right_rotate(avl_tree_node_t *root)
static avl_tree_entry_t *SAPI _avl_tree_node_right_rotate(avl_tree_entry_t *root)
{
avl_tree_node_t *left_children = root->left;
avl_tree_entry_t *left_children = root->left;
//adjust parents first
left_children->parent = root->parent;
root->parent = left_children;
@ -30,9 +30,9 @@ static avl_tree_node_t *SAPI _avl_tree_node_right_rotate(avl_tree_node_t *root)
return left_children;
}
static avl_tree_node_t *SAPI _avl_tree_node_left_rotate(avl_tree_node_t *root)
static avl_tree_entry_t *SAPI _avl_tree_node_left_rotate(avl_tree_entry_t *root)
{
avl_tree_node_t *right_children = root->right;
avl_tree_entry_t *right_children = root->right;
//adjust parents
right_children->parent = root->parent;
root->parent = right_children;
@ -47,7 +47,7 @@ static avl_tree_node_t *SAPI _avl_tree_node_left_rotate(avl_tree_node_t *root)
return right_children;
}
static avl_tree_node_t *SAPI _avl_tree_node_balance(avl_tree_node_t *node)
static avl_tree_entry_t *SAPI _avl_tree_node_balance(avl_tree_entry_t *node)
{
const int bf = _avl_tree_node_get_balance_factor(node);
@ -84,7 +84,7 @@ static avl_tree_node_t *SAPI _avl_tree_node_balance(avl_tree_node_t *node)
}
static avl_tree_node_t *SAPI _avl_tree_node_insert(avl_tree_node_t *root, avl_tree_node_t *node, int(*compare)(void *, void *), avl_tree_node_t *parent)
static avl_tree_entry_t *SAPI _avl_tree_node_insert(avl_tree_entry_t *root, avl_tree_entry_t *node, int(*compare)(avl_tree_entry_t *, avl_tree_entry_t *), avl_tree_entry_t *parent)
{
if (node == NULL)
return root;
@ -107,13 +107,13 @@ static avl_tree_node_t *SAPI _avl_tree_node_insert(avl_tree_node_t *root, avl_tr
return _avl_tree_node_balance(root);
}
static void _avl_tree_swap_nodes(avl_tree_node_t *node1, avl_tree_node_t *node2)
static void _avl_tree_swap_nodes(avl_tree_entry_t *node1, avl_tree_entry_t *node2)
{
if (node1 == NULL || node2 == NULL)
return;
avl_tree_node_t *parent = NULL;
avl_tree_node_t *child = NULL;
avl_tree_node_t *temp = NULL;
avl_tree_entry_t *parent = NULL;
avl_tree_entry_t *child = NULL;
avl_tree_entry_t *temp = NULL;
//swap node but does not change anything else other than node1,node2
if (node1->parent != NULL && node1->parent == node2)
{
@ -229,8 +229,8 @@ static void _avl_tree_swap_nodes(avl_tree_node_t *node1, avl_tree_node_t *node2)
return;
}
static avl_tree_node_t *SAPI _avl_tree_node_delete(avl_tree_node_t *root, avl_tree_node_t *node,
int (*compare)(void *, void *))
static avl_tree_entry_t *SAPI _avl_tree_node_delete(avl_tree_entry_t *root, avl_tree_entry_t *node,
int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
{
if (root == NULL || node == NULL)
return root;
@ -244,7 +244,7 @@ static avl_tree_node_t *SAPI _avl_tree_node_delete(avl_tree_node_t *root, avl_tr
// node with only one child or no child
if( (root->left == NULL) || (root->right == NULL) )
{
avl_tree_node_t *child = root->left != NULL ? root->left : root->right;
avl_tree_entry_t *child = root->left != NULL ? root->left : root->right;
if(child == NULL)
{ // 0 child
@ -260,7 +260,7 @@ static avl_tree_node_t *SAPI _avl_tree_node_delete(avl_tree_node_t *root, avl_tr
{
// node with two children: Get the inorder successor (smallest
// in the right subtree)
avl_tree_node_t *successor = root->right;
avl_tree_entry_t *successor = root->right;
while(successor->left != NULL)
successor = successor->left;
//swap fields
@ -279,8 +279,8 @@ static avl_tree_node_t *SAPI _avl_tree_node_delete(avl_tree_node_t *root, avl_tr
return root;
}
static avl_tree_node_t *SAPI _avl_tree_node_search(avl_tree_node_t *root, avl_tree_node_t *node,
int(*compare)(void *, void *))
static avl_tree_entry_t *SAPI _avl_tree_node_search(avl_tree_entry_t *root, avl_tree_entry_t *node,
int(*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
{
if(root == NULL)
return NULL;
@ -293,7 +293,7 @@ static avl_tree_node_t *SAPI _avl_tree_node_search(avl_tree_node_t *root, avl_tr
return _avl_tree_node_search(root->left, node, compare);
}
static void SAPI _avl_tree_node_init(avl_tree_node_t * it)
static void SAPI _avl_tree_node_init(avl_tree_entry_t * it)
{
if(it != NULL)
{
@ -301,35 +301,42 @@ static void SAPI _avl_tree_node_init(avl_tree_node_t * it)
it->left = NULL;
it->right = NULL;
it->parent = NULL;
linked_list_init(&it->element_list);
}
return;
}
static avl_tree_node_t *SAPI _avl_tree_node_smallest(avl_tree_node_t *root)
avl_tree_entry_t *SAPI _avl_tree_smallest(avl_tree_t *tree)
{
if (root == NULL)
if (tree == NULL)
return NULL;
while (root->left != NULL)
root = root->left;
return root;
avl_tree_entry_t* entry = tree->root;
if(entry == NULL)
return NULL;
while (entry->left != NULL)
entry = entry->left;
return entry;
}
static avl_tree_node_t *SAPI _avl_tree_node_largest(avl_tree_node_t *root)
avl_tree_entry_t *SAPI avl_tree_largest(avl_tree_t *tree)
{
if (root == NULL)
if (tree == NULL)
return NULL;
while (root->right != NULL)
root = root->right;
return root;
avl_tree_entry_t* entry = tree->root;
if(entry == NULL)
return NULL;
while (entry->right != NULL)
entry = entry->right;
return entry;
}
static avl_tree_node_t *SAPI _avl_tree_node_next(avl_tree_node_t *it)
avl_tree_entry_t *SAPI avl_tree_larger(avl_tree_entry_t *it)
{
if (it == NULL)
return NULL;
avl_tree_node_t * root = it;
avl_tree_entry_t * root = it;
if (root->right != NULL)
{
root = root->right;
@ -349,11 +356,11 @@ static avl_tree_node_t *SAPI _avl_tree_node_next(avl_tree_node_t *it)
}
}
static avl_tree_node_t *SAPI _avl_tree_node_prev(avl_tree_node_t *it)
avl_tree_entry_t *SAPI avl_tree_smaller(avl_tree_entry_t *it)
{
if (it == NULL)
return NULL;
avl_tree_node_t * root = it;
avl_tree_entry_t * root = it;
if (root->left != NULL)
{
root = root->left;
@ -373,57 +380,70 @@ static avl_tree_node_t *SAPI _avl_tree_node_prev(avl_tree_node_t *it)
}
}
avl_tree_node_t * SAPI avl_tree_search(avl_tree_t *tree, avl_tree_node_t * node, int (*compare)(void *, void *))
avl_tree_entry_t * SAPI avl_tree_search(avl_tree_t *tree, avl_tree_entry_t * node, int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
{
return _avl_tree_node_search(tree->root, node, compare);
}
void SAPI avl_tree_insert(avl_tree_t *tree, void *data, int (*compare)(void *, void *))
void SAPI avl_tree_insert(avl_tree_t *tree, void *data, int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
{
if(tree != NULL && data != NULL && compare != NULL)
{
if(avl_tree_search(tree, data, compare) == NULL)
{
tree->root = _avl_tree_node_insert(tree->root, data, compare, NULL);
tree->size++;
}
}
return;
}
void SAPI avl_tree_delete(avl_tree_t *tree, void *data, int (*compare)(void *, void *))
void SAPI avl_tree_delete(avl_tree_t *tree, void *data, int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *))
{
if(tree != NULL && data != NULL && compare != NULL && tree->size != 0)
if(tree != NULL && data != NULL && compare != NULL)
{
if(avl_tree_search(tree, data, compare) != NULL)
{
tree->root = _avl_tree_node_delete(tree->root, data, compare);
tree->size--;
}
}
return;
}
int32_t SAPI avl_tree_size(avl_tree_t *tree)
{
if(tree == NULL)
return -1;
if(tree->root == NULL)
return 0;
int32_t size= 0;
avl_tree_entry_t* entry = avl_tree_smallest(tree);
while(entry != NULL)
{
size++;
entry = avl_tree_larger(entry);
}
return size;
}
void SAPI avl_tree_init(avl_tree_t * tree)
{
if(tree != NULL)
{
tree->root = NULL;
tree->size = 0;
}
return;
}
// TESTS
static int SAPI avl_tree_node_calculate_height(avl_tree_node_t *tree)
static int SAPI avl_tree_node_calculate_height(avl_tree_entry_t *tree)
{
if (tree == NULL)
return -1;
return max_32(avl_tree_node_calculate_height(tree->left), avl_tree_node_calculate_height(tree->right)) + 1;
}
static int SAPI avl_tree_node_test(avl_tree_node_t *tree, int (*compare)(void*, void*))
static int SAPI avl_tree_node_test(avl_tree_entry_t *tree, int (*compare)(void*, void*))
{
if (tree == NULL)
return 1;

View File

@ -1,28 +1,38 @@
#ifndef _AVL_TREE_H_
#define _AVL_TREE_H_
#include "../../../sys/kdef.h"
#include "../../../sys/sys_info.h"
typedef struct _avl_tree_node_t
typedef struct _avl_tree_entry_t
{
struct _avl_tree_node_t * left;
struct _avl_tree_node_t * right;
struct _avl_tree_node_t * parent;
struct _avl_tree_entry_t * left;
struct _avl_tree_entry_t * right;
struct _avl_tree_entry_t * parent;
linked_list_t element_list;
linked_list_entry_t list_entry;
int height;
} avl_tree_node_t;
} avl_tree_entry_t;
typedef struct
{
avl_tree_node_t * root;
int size;
avl_tree_entry_t * root;
} avl_tree_t;
avl_tree_node_t * SAPI avl_tree_search(avl_tree_t *tree, avl_tree_node_t * node, int (*compare)(void *, void *));
avl_tree_entry_t * SAPI avl_tree_search(avl_tree_t *tree, avl_tree_entry_t * node, int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *));
void SAPI avl_tree_insert(avl_tree_t *tree, void *data, int (*compare)(void *, void *));
void SAPI avl_tree_insert(avl_tree_t *tree, void *data, int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *));
void SAPI avl_tree_delete(avl_tree_t *tree, void *data, int (*compare)(void *, void *));
void SAPI avl_tree_delete(avl_tree_t *tree, void *data, int (*compare)(avl_tree_entry_t *, avl_tree_entry_t *));
void SAPI avl_tree_init(avl_tree_t * tree);
avl_tree_entry_t* SAPI avl_tree_largest(avl_tree_t *tree);
avl_tree_entry_t* SAPI avl_tree_smallest(avl_tree_t *tree);
avl_tree_entry_t* SAPI avl_tree_larger(avl_tree_entry_t* entry);
avl_tree_entry_t* SAPI avl_tree_smaller(avl_tree_entry_t* entry);
#endif

View File

@ -11,7 +11,7 @@ typedef struct
{
uint64_t base_addr;
uint64_t page_count;
linked_list_node_t list_node;
linked_list_entry_t list_node;
} memory_descriptor_node_t;
typedef struct {
@ -26,7 +26,7 @@ typedef struct
uint64_t base_addr;
uint64_t size;
char* name;
linked_list_node_t list_node;
linked_list_entry_t list_node;
} module_descriptor_node_t;
typedef struct {