private bool Remove(string key, AlphaTrieNode startingNode) { if (startingNode.Value != null && startingNode.Value.Key == key) { startingNode.Value = null; return(true); } if (startingNode.Nodes != null) { for (int i = 0; i < NodeCount; i++) { AlphaTrieNode nextNode = startingNode.Nodes[i]; if (nextNode != null) { bool retVal = Remove(key, nextNode); if (retVal == true) { return(true); } } } } return(false); }
// Searches the trie for a node starting with the given key. If multiple are found, null will be returned. public IEnumerable <KeyValueReference <string, T> > FindByKeyStart(string _key) { string key = _key.ToLower(); AlphaTrieNode currentNode = rootNode; int level = -1; while (level < key.Length - 1) { level++; // Found the key exactly here, so return it and all of its underlings. if (currentNode.Value != null && currentNode.Value.Key == key) { foreach (var retKV in Traverse(currentNode)) { yield return(retKV); } } int ix; try { ix = AlphaTrieNode.CharToTrieNodeIndex(key[level]); } catch (InvalidOperationException) { yield break; } // Ran into a dead end. if (currentNode.Nodes == null || currentNode.Nodes[ix] == null) { if (currentNode.Value == null) { yield break; } if (currentNode.Value.Key.StartsWith(key)) { yield return(currentNode.Value); } yield break; } currentNode = currentNode.Nodes[ix]; } foreach (var retKV in Traverse(currentNode)) { yield return(retKV); } }
private IEnumerable <KeyValueReference <string, T> > Traverse(AlphaTrieNode startingNode) { if (startingNode.Value != null) { yield return(startingNode.Value); } if (startingNode.Nodes != null) { for (int i = 0; i < NodeCount; i++) { AlphaTrieNode nextNode = startingNode.Nodes[i]; if (nextNode != null) { foreach (var newNode in this.Traverse(nextNode)) { yield return(newNode); } } } } }
public AlphaTrie() { rootNode = new AlphaTrieNode(); }
private void Insert(AlphaTrieNode node, KeyValueReference <string, T> insKV, int level) { if (node.Value != null && node.Value.Key == insKV.Key) { throw new InvalidOperationException("Attempted to insert duplicate key into the trie."); } if (node.Nodes == null && node.Value == null) { node.Value = insKV; return; } if (node.Nodes == null && node.Value != null) { node.Nodes = new AlphaTrieNode[NodeCount]; // Only move the current Value if it isn't exactly there. if (node.Value.Key.Length > level) { KeyValueReference <string, T> moveKV = node.Value; node.Value = null; int im = AlphaTrieNode.CharToTrieNodeIndex(moveKV.Key[level]); node.Nodes[im] = new AlphaTrieNode(moveKV); node.Branches++; } // If ours fits perfectly, we know we had to move the old one. if (insKV.Key.Length == level) { node.Value = insKV; return; } int ii = AlphaTrieNode.CharToTrieNodeIndex(insKV.Key[level]); if (node.Nodes[ii] == null) { node.Nodes[ii] = new AlphaTrieNode(insKV); node.Branches++; } else { Insert(node.Nodes[ii], insKV, level + 1); } return; } if (node.Nodes != null) { // If we go exactly here, stick it in the Value. if (insKV.Key.Length == level) { node.Value = insKV; return; } // Otherwise, make new path or follow the old path. int ii = AlphaTrieNode.CharToTrieNodeIndex(insKV.Key[level]); if (node.Nodes[ii] == null) { node.Nodes[ii] = new AlphaTrieNode(insKV); node.Branches++; } else { Insert(node.Nodes[ii], insKV, level + 1); } } }