1 /* 2 Copyright (c) 2015-2021 Timur Gafarov 3 4 Boost Software License - Version 1.0 - August 17th, 2003 5 6 Permission is hereby granted, free of charge, to any person or organization 7 obtaining a copy of the software and accompanying documentation covered by 8 this license (the "Software") to use, reproduce, display, distribute, 9 execute, and transmit the Software, and to prepare derivative works of the 10 Software, and to permit third-parties to whom the Software is furnished to 11 do so, all subject to the following: 12 13 The copyright notices in the Software and this entire statement, including 14 the above license grant, this restriction and the following disclaimer, 15 must be included in all copies of the Software, in whole or in part, and 16 all derivative works of the Software, unless such copies or derivative 17 works are solely in the form of machine-executable object code generated by 18 a source language processor. 19 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 DEALINGS IN THE SOFTWARE. 27 */ 28 29 /** 30 * Binary search tree 31 * 32 * Copyright: Timur Gafarov 2015-2021. 33 * License: $(LINK2 boost.org/LICENSE_1_0.txt, Boost License 1.0). 34 * Authors: Timur Gafarov, Andrey Penechko 35 */ 36 module dlib.container.bst; 37 38 import dlib.core.memory; 39 40 /** 41 * GC-free binary search tree implementation. 42 */ 43 class BST(T) 44 { 45 bool root; 46 BST left = null; 47 BST right = null; 48 int key = 0; 49 50 T value; 51 52 this() 53 { 54 root = true; 55 } 56 57 this(int k, T v) 58 { 59 key = k; 60 value = v; 61 root = false; 62 } 63 64 ~this() 65 { 66 clear(); 67 } 68 69 void insert(int k, T v) 70 { 71 if (k < key) 72 { 73 if (left is null) left = allocate!(BST)(k, v); 74 else left.insert(k, v); 75 } 76 else if (k > key) 77 { 78 if (right is null) right = allocate!(BST)(k, v); 79 else right.insert(k, v); 80 } 81 else value = v; 82 } 83 84 BST find(int k) 85 { 86 if (k < key) 87 { 88 if (left !is null) return left.find(k); 89 else return null; 90 } 91 else if (k > key) 92 { 93 if (right !is null) return right.find(k); 94 else return null; 95 } 96 else return this; 97 } 98 99 protected BST findLeftMost() 100 { 101 if (left is null) return this; 102 else return left.findLeftMost(); 103 } 104 105 void remove(int k, BST par = null) 106 { 107 if (k < key) 108 { 109 if (left !is null) left.remove(k, this); 110 else return; 111 } 112 else if (k > key) 113 { 114 if (right !is null) right.remove(k, this); 115 else return; 116 } 117 else 118 { 119 if (left !is null && right !is null) 120 { 121 auto m = right.findLeftMost(); 122 key = m.key; 123 value = m.value; 124 right.remove(key, this); 125 } 126 else if (this == par.left) 127 { 128 par.left = (left !is null)? left : right; 129 //deallocate(value); 130 } 131 else if (this == par.right) 132 { 133 par.right = (left !is null)? left : right; 134 //deallocate(value); 135 } 136 } 137 } 138 139 void traverse(void function(int, T) func) 140 { 141 if (left !is null) 142 left.traverse(func); 143 if (!root) 144 func(key, value); 145 if (right !is null) 146 right.traverse(func); 147 } 148 149 int opApply(scope int delegate(int, ref T) dg) 150 { 151 int result = 0; 152 153 if (left !is null) 154 { 155 result = left.opApply(dg); 156 if (result) 157 return result; 158 } 159 160 if (!root) 161 dg(key, value); 162 163 if (right !is null) 164 { 165 result = right.opApply(dg); 166 if (result) 167 return result; 168 } 169 170 return result; 171 } 172 173 void clear() 174 { 175 if (left !is null) 176 { 177 left.clear(); 178 deallocate(left); 179 left = null; 180 } 181 if (right !is null) 182 { 183 right.clear(); 184 deallocate(right); 185 right = null; 186 } 187 if (!root) 188 { 189 //deallocate(value); 190 } 191 } 192 193 //mixin ManualModeImpl; 194 // mixin FreeImpl; 195 }