void Add( ref SortingTreeNode node, int parent_id, int K, ushort V ) { node.key = K; node.value = V; node.lesser = -1; node.greater = -1; node.parent = parent_id; node.children = 0; }
void ScanAdd( ref SortingTreeNode node, int node_id, int K, ushort V ) { if( K < node.key ) { if( node.lesser == -1 ) { node.children++; Add( ref storage[used], node_id, K, V ); node.lesser = used; used++; } else { node.children++; ScanAdd( ref storage[node.lesser], node.lesser, K, V ); Balance( ref node, node_id ); } } else if( K >= node.key ) { if( node.greater == -1 ) { node.children++; Add( ref storage[used], node_id, K, V ); node.greater = used; used++; } else { node.children++; ScanAdd( ref storage[node.greater], node.greater, K, V ); Balance( ref node, node_id ); } } }
void Balance( ref SortingTreeNode node, int node_id ) { if( !AutoBalance ) return; int left_children = node.lesser == -1 ? 0 : ( storage[node.lesser].children + 1 ); int right_children = node.greater == -1 ? 0 : ( storage[node.greater].children + 1 ); #if USE_REFS_ROTATE int parent = node.parent; #endif if( left_children == 0 ) { if( right_children > 1 ) { #if DEBUG_BALANCING left_shallow_swaps++; #endif #if !USE_REFS_ROTATE RotateLeft( ref node, node_id ); #else if( parent != -1 ) RotateLeft( ref node, node_id, ref storage[parent], ref storage[node.greater] ); else RotateLeft( ref node, node_id, ref null_node, ref storage[node.greater] ); #endif } } else if( right_children == 0 ) { if( left_children > 1 ) { #if DEBUG_BALANCING right_shallow_swaps++; #endif #if !USE_REFS_ROTATE RotateRight( ref node, node_id ); #else if( parent != -1 ) RotateRight( ref node, node_id, ref storage[parent], ref storage[node.lesser] ); else RotateRight( ref node, node_id, ref null_node, ref storage[node.lesser] ); #endif } } else if( right_children > ( left_children * 3 ) ) { #if DEBUG_BALANCING left_swaps++; #endif #if !USE_REFS_ROTATE RotateLeft( ref node, node_id ); #else if( parent == -1 ) RotateLeft( ref node, node_id, ref null_node, ref storage[node.greater] ); else RotateLeft( ref node, node_id, ref storage[parent], ref storage[node.greater] ); #endif Balance( ref storage[node.lesser], node.lesser ); } else if( left_children > ( right_children * 3 ) ) { #if DEBUG_BALANCING right_swaps++; #endif #if !USE_REFS_ROTATE RotateRight( ref node, node_id ); #else if( parent == -1 ) RotateRight( ref node, node_id, ref null_node, ref storage[node.lesser] ); else RotateRight( ref node, node_id, ref storage[parent], ref storage[node.lesser] ); #endif Balance( ref storage[node.greater], node.greater ); } }
void RotateRight( ref SortingTreeNode node, int node_id ) { if( node.parent == -1 ) { root = node.lesser; storage[root].parent = -1; } else { if( storage[node.parent].lesser == node_id ) storage[node.parent].lesser = node.lesser; else storage[node.parent].greater = node.lesser; storage[node.lesser].parent = node.parent; } node.children -= ( storage[node.lesser].children + 1 ); node.parent = node.lesser; int temp = storage[node.lesser].greater; node.lesser = temp; storage[node.parent].greater = node_id; // actually oldnode.lesser if( temp >= 0 ) { storage[temp].parent = node_id; storage[node.parent].children -= ( storage[temp].children + 1 ); node.children += ( storage[temp].children + 1 ); } storage[node.parent].children += ( node.children + 1 ); }
void RotateRight( ref SortingTreeNode node, int node_id, ref SortingTreeNode parent, ref SortingTreeNode lesser ) { if( node.parent == -1 ) { root = node.lesser; storage[root].parent = -1; } else { if( parent.lesser == node_id ) parent.lesser = node.lesser; else parent.greater = node.lesser; lesser.parent = node.parent; } node.children -= ( lesser.children + 1 ); node.parent = node.lesser; int temp = lesser.greater; node.lesser = temp; lesser.greater = node_id; // actually oldnode.lesser if( temp >= 0 ) { storage[temp].parent = node_id; lesser.children -= ( storage[temp].children + 1 ); node.children += ( storage[temp].children + 1 ); } lesser.children += ( node.children + 1 ); }
void RotateLeft( ref SortingTreeNode node, int node_id, ref SortingTreeNode parent, ref SortingTreeNode greater ) { if( node.parent == -1 ) { root = node.greater; storage[root].parent = -1; } else { if( parent.lesser == node_id ) parent.lesser = node.greater; else parent.greater = node.greater; greater.parent = node.parent; } node.children -= ( greater.children + 1 ); node.parent = node.greater; int temp = greater.lesser; node.greater = temp; greater.lesser = node_id; if( temp >= 0 ) { storage[temp].parent = node_id; greater.children -= ( storage[temp].children + 1 ); node.children += ( storage[temp].children + 1 ); } greater.children += ( node.children + 1 ); }