util: tree-based associative container
This commit is contained in:
		
							
								
								
									
										80
									
								
								util/test_tree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								util/test_tree.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					//$CC -g test_tree.c tree.c ../driver/random/random.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "stdlib.h"
 | 
				
			||||||
 | 
					#include "stdio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tree.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_Tree *tree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void insert(int a) {
 | 
				
			||||||
 | 
						bool new;
 | 
				
			||||||
 | 
						int *d = tree_Insert(tree, a, &new);
 | 
				
			||||||
 | 
						if (new)
 | 
				
			||||||
 | 
							*d = 1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							(*d)++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int count(int a) {
 | 
				
			||||||
 | 
						int *d = tree_Find(tree, a);
 | 
				
			||||||
 | 
						if (!d)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return *d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void delete (int a) {
 | 
				
			||||||
 | 
						tree_Node *node = tree_FindNode(tree, a);
 | 
				
			||||||
 | 
						if (!node)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(*(int *)node->data)--;
 | 
				
			||||||
 | 
						if ((*(int *)node->data) == 0)
 | 
				
			||||||
 | 
							tree_Delete(tree, node);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
						tree = tree_Create(sizeof(int));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						insert(1);
 | 
				
			||||||
 | 
						insert(2);
 | 
				
			||||||
 | 
						insert(3);
 | 
				
			||||||
 | 
						insert(6);
 | 
				
			||||||
 | 
						insert(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("%d\n", count(2));
 | 
				
			||||||
 | 
						printf("%d\n", count(4));
 | 
				
			||||||
 | 
						printf("%d\n", count(1));
 | 
				
			||||||
 | 
						delete (1);
 | 
				
			||||||
 | 
						printf("%d\n", count(1));
 | 
				
			||||||
 | 
						delete (1);
 | 
				
			||||||
 | 
						printf("%d\n", count(1));
 | 
				
			||||||
 | 
						delete (1);
 | 
				
			||||||
 | 
						printf("%d\n", count(1));
 | 
				
			||||||
 | 
						delete (2);
 | 
				
			||||||
 | 
						printf("%d\n", count(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						insert(7);
 | 
				
			||||||
 | 
						insert(10);
 | 
				
			||||||
 | 
						insert(54);
 | 
				
			||||||
 | 
						insert(18);
 | 
				
			||||||
 | 
						insert(63);
 | 
				
			||||||
 | 
						insert(39);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tree_Node *i = tree_FirstNode(tree);
 | 
				
			||||||
 | 
						while (i) {
 | 
				
			||||||
 | 
							printf(" %d", (int)i->key);
 | 
				
			||||||
 | 
							i = tree_Node_Next(i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						i = tree_LastNode(tree);
 | 
				
			||||||
 | 
						while (i) {
 | 
				
			||||||
 | 
							printf(" %d", (int)i->key);
 | 
				
			||||||
 | 
							i = tree_Node_Previous(i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										164
									
								
								util/tree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								util/tree.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tree.h"
 | 
				
			||||||
 | 
					#include "tree_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../main.h"
 | 
				
			||||||
 | 
					#include "../memory/memory.h"
 | 
				
			||||||
 | 
					#include "../driver/random/random.h"
 | 
				
			||||||
 | 
					#include "string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create allocates and creates a new default Tree object.
 | 
				
			||||||
 | 
					tree_Tree *tree_Create(uintptr_t objectSize) {
 | 
				
			||||||
 | 
						tree_Tree *t  = kMalloc(sizeof(tree_Tree));
 | 
				
			||||||
 | 
						t->objectSize = objectSize;
 | 
				
			||||||
 | 
						t->size       = 0;
 | 
				
			||||||
 | 
						t->root       = 0;
 | 
				
			||||||
 | 
						return t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline tree_Node *__tree_NewNode(tree_Tree *t, uintptr_t key, tree_Node *father, uintptr_t internal) {
 | 
				
			||||||
 | 
						t->size++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tree_Node *node = kMalloc(sizeof(tree_Node) - 1 + t->objectSize);
 | 
				
			||||||
 | 
						node->left = node->right = 0;
 | 
				
			||||||
 | 
						node->father             = father;
 | 
				
			||||||
 | 
						node->key                = key;
 | 
				
			||||||
 | 
						node->internal           = internal;
 | 
				
			||||||
 | 
						return node;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __tree_DestroyNodes(tree_Node *node) {
 | 
				
			||||||
 | 
						if (node->left)
 | 
				
			||||||
 | 
							__tree_DestroyNodes(node->left);
 | 
				
			||||||
 | 
						if (node->right)
 | 
				
			||||||
 | 
							__tree_DestroyNodes(node->right);
 | 
				
			||||||
 | 
						kFree(node);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tree_Destroy(tree_Tree *tree) {
 | 
				
			||||||
 | 
						if (tree->root)
 | 
				
			||||||
 | 
							__tree_DestroyNodes(tree->root);
 | 
				
			||||||
 | 
						kFree(tree);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Will not return NULL
 | 
				
			||||||
 | 
					// SysV ABI because of the 6 arguments
 | 
				
			||||||
 | 
					SYSV_ABI static tree_Node *__tree_InsertNodes(tree_Tree *t, tree_Node *node, tree_Node *father, uintptr_t key, tree_Node **result, bool *added) {
 | 
				
			||||||
 | 
						if (!node) {
 | 
				
			||||||
 | 
							if (added)
 | 
				
			||||||
 | 
								*added = true;
 | 
				
			||||||
 | 
							return *result = __tree_NewNode(t, key, father, random_Rand() ^ key);
 | 
				
			||||||
 | 
						} else if (key < node->key) {
 | 
				
			||||||
 | 
							node->left = __tree_InsertNodes(t, node->left, node, key, result, added);
 | 
				
			||||||
 | 
							return node;
 | 
				
			||||||
 | 
						} else if (key > node->key) {
 | 
				
			||||||
 | 
							node->right = __tree_InsertNodes(t, node->right, node, key, result, added);
 | 
				
			||||||
 | 
							return node;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (added)
 | 
				
			||||||
 | 
								*added = false;
 | 
				
			||||||
 | 
							*result = node;
 | 
				
			||||||
 | 
							return node;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_Node *tree_InsertNode(tree_Tree *t, uintptr_t key, bool *added) {
 | 
				
			||||||
 | 
						tree_Node *result;
 | 
				
			||||||
 | 
						t->root = __tree_InsertNodes(t, t->root, 0, key, &result, added);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*added)
 | 
				
			||||||
 | 
							__tree_treap_Adjust(result, &t->root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *tree_Insert(tree_Tree *t, uintptr_t key, bool *added) {
 | 
				
			||||||
 | 
						return tree_InsertNode(t, key, added)->data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static tree_Node *__tree_FindNode(tree_Node *node, uintptr_t key) {
 | 
				
			||||||
 | 
						if (!node)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						else if (key < node->key)
 | 
				
			||||||
 | 
							return __tree_FindNode(node->left, key);
 | 
				
			||||||
 | 
						else if (key > node->key)
 | 
				
			||||||
 | 
							return __tree_FindNode(node->right, key);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return node;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_Node *tree_FindNode(tree_Tree *t, uintptr_t key) {
 | 
				
			||||||
 | 
						return __tree_FindNode(t->root, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *tree_Find(tree_Tree *t, uintptr_t key) {
 | 
				
			||||||
 | 
						tree_Node *node = tree_FindNode(t, key);
 | 
				
			||||||
 | 
						if (!node)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return node->data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tree_Delete(tree_Tree *t, tree_Node *node) {
 | 
				
			||||||
 | 
						while (node->left && node->right)
 | 
				
			||||||
 | 
							if (node->left->internal < node->right->internal)
 | 
				
			||||||
 | 
								__tree_Rotate(node->left, &t->root);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								__tree_Rotate(node->right, &t->root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (node == t->root)
 | 
				
			||||||
 | 
							t->root = (node->left ? node->left : node->right);
 | 
				
			||||||
 | 
						__tree_Connect(node->father, (node->left ? node->left : node->right), __tree_Tell(node));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kFree(node);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_Node *tree_FirstNode(tree_Tree *tree) {
 | 
				
			||||||
 | 
						tree_Node *result = tree->root;
 | 
				
			||||||
 | 
						while (result->left)
 | 
				
			||||||
 | 
							result = result->left;
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_Node *tree_LastNode(tree_Tree *tree) {
 | 
				
			||||||
 | 
						tree_Node *result = tree->root;
 | 
				
			||||||
 | 
						while (result->right)
 | 
				
			||||||
 | 
							result = result->right;
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_Node *tree_Node_Next(tree_Node *node) {
 | 
				
			||||||
 | 
						if (node->right) {
 | 
				
			||||||
 | 
							tree_Node *result = node->right;
 | 
				
			||||||
 | 
							while (result->left)
 | 
				
			||||||
 | 
								result = result->left;
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							tree_Node *result = node;
 | 
				
			||||||
 | 
							while (result->father && __tree_Tell(result) == __tree_Right)
 | 
				
			||||||
 | 
								result = result->father;
 | 
				
			||||||
 | 
							return result->father;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Node_Previous returns the previous node. Returns NULL if first.
 | 
				
			||||||
 | 
					tree_Node *tree_Node_Previous(tree_Node *node) {
 | 
				
			||||||
 | 
						if (node->left) {
 | 
				
			||||||
 | 
							tree_Node *result = node->left;
 | 
				
			||||||
 | 
							while (result->right)
 | 
				
			||||||
 | 
								result = result->right;
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							tree_Node *result = node;
 | 
				
			||||||
 | 
							while (result->father && __tree_Tell(result) == __tree_Left)
 | 
				
			||||||
 | 
								result = result->father;
 | 
				
			||||||
 | 
							return result->father;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								util/tree.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								util/tree.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct __tree_Node {
 | 
				
			||||||
 | 
						uintptr_t           key;          // node key
 | 
				
			||||||
 | 
						struct __tree_Node *left, *right; // left and right sons
 | 
				
			||||||
 | 
						struct __tree_Node *father;       // father node
 | 
				
			||||||
 | 
						uintptr_t           internal;     // internal data for balanced trees
 | 
				
			||||||
 | 
						char                data[1];      // placeholder for object data
 | 
				
			||||||
 | 
					} tree_Node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tree is a basic tree-based associative container.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Right now it's a Treap.
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						uintptr_t  objectSize; // size in bytes of the object
 | 
				
			||||||
 | 
						tree_Node *root;       // root of the tree, NULL if empty
 | 
				
			||||||
 | 
						uintptr_t  size;       // number of objects in the tree
 | 
				
			||||||
 | 
					} tree_Tree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create allocates and creates a new default Tree object.
 | 
				
			||||||
 | 
					tree_Tree *tree_Create(uintptr_t objectSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Destroy properly frees all data related to the structure, and itself.
 | 
				
			||||||
 | 
					void tree_Destroy(tree_Tree *tree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Insert inserts a new object (or locates an existing one).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// If *added is not NULL, it is set to true if the key does
 | 
				
			||||||
 | 
					// not exist and is actually added.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Newly allocated data is not zeroed, nor initialized in any way.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Returns the pointer to the newly allocated (or existing) data.
 | 
				
			||||||
 | 
					void *tree_Insert(tree_Tree *tree, uintptr_t key, bool *added);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// InsertNode does the same as Insert, but returns Node* instead of data.
 | 
				
			||||||
 | 
					tree_Node *tree_InsertNode(tree_Tree *tree, uintptr_t key, bool *added);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Find locates an existing object by its key.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Returns NULL if the object does not exist.
 | 
				
			||||||
 | 
					void *tree_Find(tree_Tree *tree, uintptr_t key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FindNode returns an existing tree node by its key.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Used for iterating the tree objects.
 | 
				
			||||||
 | 
					tree_Node *tree_FindNode(tree_Tree *tree, uintptr_t key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FirstNode returns the first node in increasing order.
 | 
				
			||||||
 | 
					tree_Node *tree_FirstNode(tree_Tree *tree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LastNode returns the last node in increasing order.
 | 
				
			||||||
 | 
					tree_Node *tree_LastNode(tree_Tree *tree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete deletes an existing node from the tree.
 | 
				
			||||||
 | 
					void tree_Delete(tree_Tree *tree, tree_Node *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Node_Next returns the next node. Returns NULL if the node is the last.
 | 
				
			||||||
 | 
					tree_Node *tree_Node_Next(tree_Node *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Node_Previous returns the previous node. Returns NULL if first.
 | 
				
			||||||
 | 
					tree_Node *tree_Node_Previous(tree_Node *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										60
									
								
								util/tree_internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								util/tree_internal.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tree.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
						__tree_Left,
 | 
				
			||||||
 | 
						__tree_Right,
 | 
				
			||||||
 | 
					} __tree_ConnectType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline __tree_ConnectType __tree_ConnectType_Invert(__tree_ConnectType type) {
 | 
				
			||||||
 | 
						return (__tree_ConnectType)(!type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline __tree_ConnectType __tree_Tell(tree_Node *son) {
 | 
				
			||||||
 | 
						if (!son->father)
 | 
				
			||||||
 | 
							return __tree_Left;
 | 
				
			||||||
 | 
						if (son->father->left == son)
 | 
				
			||||||
 | 
							return __tree_Left;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return __tree_Right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline tree_Node *__tree_Get(tree_Node *father, __tree_ConnectType type) {
 | 
				
			||||||
 | 
						return (type == __tree_Left) ? father->left : father->right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void __tree_Connect(tree_Node *father, tree_Node *son, __tree_ConnectType type) {
 | 
				
			||||||
 | 
						if (son)
 | 
				
			||||||
 | 
							son->father = father;
 | 
				
			||||||
 | 
						if (father) {
 | 
				
			||||||
 | 
							if (type == __tree_Left)
 | 
				
			||||||
 | 
								father->left = son;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								father->right = son;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Rotates the node up.
 | 
				
			||||||
 | 
					static inline void __tree_Rotate(tree_Node *node, tree_Node **root) {
 | 
				
			||||||
 | 
						if (!node->father)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__tree_ConnectType type = __tree_Tell(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tree_Node *f = node->father,
 | 
				
			||||||
 | 
								  *b = __tree_Get(node, __tree_ConnectType_Invert(type));
 | 
				
			||||||
 | 
						__tree_Connect(f->father, node, __tree_Tell(f));
 | 
				
			||||||
 | 
						__tree_Connect(node, f, __tree_ConnectType_Invert(type));
 | 
				
			||||||
 | 
						__tree_Connect(f, b, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!node->father)
 | 
				
			||||||
 | 
							*root = node;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Adjust the tree as a Treap
 | 
				
			||||||
 | 
					static inline void __tree_treap_Adjust(tree_Node *node, tree_Node **root) {
 | 
				
			||||||
 | 
						while (node->father && node->father->internal > node->internal)
 | 
				
			||||||
 | 
							__tree_Rotate(node, root);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user