public LandPriceInfoTree() { root = null; _count = 0; }
// Recursive destruction of binary search tree, called by method clear // and destroy. Can be used to kill a sub-tree of a larger tree. // This is a hanger on from its Delphi origins, it might be dispensable // given the garbage collection abilities of .NET private void killTree(ref TTreeNode p) { if (p != null) { killTree(ref p.left); killTree(ref p.right); p = null; } }
public TTreeNode(int id, int hsk, double d,int smt) { this.oid = id; dongia = d; hesok = hsk; somattien = smt; left = null; right = null; }
// Simple 'drawing' routines private string drawNode(TTreeNode node) { if (node == null) return "empty"; if ((node.left == null) && (node.right == null)) return node.oid.ToString(); if ((node.left != null) && (node.right == null)) return node.oid.ToString() + "(" + drawNode(node.left) + ", _)"; if ((node.right != null) && (node.left == null)) return node.oid.ToString() + "(_, " + drawNode(node.right) + ")"; return node.oid.ToString() + "(" + drawNode(node.left) + ", " + drawNode(node.right) + ")"; }
// Searches for a node with name key, name. If found it returns a reference // to the node and to thenodes parent. Else returns null. private TTreeNode findParent(int obj, ref TTreeNode parent,string key) { TTreeNode np = root; parent = null; int cmp; while (np != null) { //cmp = String.Compare(name, np.name); if (key == "hsk") { if (obj == np.hesok) // found ! return np; if (obj < np.hesok) { parent = np; np = np.left; } else { parent = np; np = np.right; } } else if (key == "oid") { if (obj == np.oid) // found ! return np; if (obj < np.oid) { parent = np; np = np.left; } else { parent = np; np = np.right; } } } return null; // Return null to indicate failure to find name }
// Recursively locates an empty slot in the binary tree and inserts the node private void add(TTreeNode node, ref TTreeNode tree) { if (tree == null) tree = node; else { // If we find a node with the same name then it's // a duplicate and we can't continue //int comparison = String.Compare(node.name, tree.name); if (node.oid==tree.oid) throw new Exception(); if (node.oid < tree.oid) { add(node, ref tree.left); } else { add(node, ref tree.right); } } }
public void Visit(TTreeNode node) { if (node == null) { return; } _lstOid.Add(node.oid); _lstHsk.Add(node.hesok); //MessageBox.Show(string.Format("lien 522 LandpriceInfoTree, len ={0},oid={1}", _lstOid.Count, _lstOid[_lstOid.Count - 1])); if (node.left != null) { Visit(node.left); } if(node.right!=null) { Visit(node.right); } }
public TTreeNode insert(int oid, int hsk, double d) { TTreeNode node = new TTreeNode(oid, hsk, d); try { if (root == null) root = node; else add(node, ref root); _count++; return node; } catch (Exception) { return null; } }
/// <summary> /// Find the next ordinal node starting at node startNode. /// Due to the structure of a binary search tree, the /// successor node is simply the left most node on the right branch. /// </summary> /// <param name="startNode">Name key to use for searching</param> /// <param name="parent">Returns the parent node if search successful</param> /// <returns>Returns a reference to the node if successful, else null</returns> public TTreeNode findSuccessor(TTreeNode startNode, ref TTreeNode parent) { parent = startNode; // Look for the left-most node on the right side startNode = startNode.right; while (startNode.left != null) { parent = startNode; startNode = startNode.left; } return startNode; }
/// <summary> /// Delete a given node. This is the more complex method in the binary search /// class. The method considers three senarios, 1) the deleted node has no /// children; 2) the deleted node as one child; 3) the deleted node has two /// children. Case one and two are relatively simple to handle, the only /// unusual considerations are when the node is the root node. Case 3) is /// much more complicated. It requires the location of the successor node. /// The node to be deleted is then replaced by the sucessor node and the /// successor node itself deleted. Throws an exception if the method fails /// to locate the node for deletion. /// </summary> /// <param name="key">Name key of node to delete</param> public void delete(int obj,string key) { TTreeNode parent = null; // First find the node to delete and its parent TTreeNode nodeToDelete = findParent(obj, ref parent,key); if (nodeToDelete == null) throw new Exception("Unable to delete node: " + key.ToString()); // can't find node, then say so // Three cases to consider, leaf, one child, two children // If it is a simple leaf then just null what the parent is pointing to if ((nodeToDelete.left == null) && (nodeToDelete.right == null)) { if (parent == null) { root = null; return; } // find out whether left or right is associated // with the parent and null as appropriate if (parent.left == nodeToDelete) parent.left = null; else parent.right = null; _count--; return; } // One of the children is null, in this case // delete the node and move child up if (nodeToDelete.left == null) { // Special case if we're at the root if (parent == null) { root = nodeToDelete.right; return; } // Identify the child and point the parent at the child if (parent.left == nodeToDelete) parent.right = nodeToDelete.right; else parent.left = nodeToDelete.right; nodeToDelete = null; // Clean up the deleted node _count--; return; } // One of the children is null, in this case // delete the node and move child up if (nodeToDelete.right == null) { // Special case if we're at the root if (parent == null) { root = nodeToDelete.left; return; } // Identify the child and point the parent at the child if (parent.left == nodeToDelete) parent.left = nodeToDelete.left; else parent.right = nodeToDelete.left; nodeToDelete = null; // Clean up the deleted node _count--; return; } // Both children have nodes, therefore find the successor, // replace deleted node with successor and remove successor // The parent argument becomes the parent of the successor TTreeNode successor = findSuccessor(nodeToDelete, ref parent); // Make a copy of the successor node TTreeNode tmp = new TTreeNode(successor.oid, successor.hesok,successor.dongia,successor.somattien); // Find out which side the successor parent is pointing to the // successor and remove the successor if (parent.left == successor) parent.left = null; else parent.right = null; // Copy over the successor values to the deleted node position nodeToDelete.oid = tmp.oid; nodeToDelete.hesok = tmp.hesok; nodeToDelete.somattien = tmp.somattien; nodeToDelete.dongia = tmp.dongia; _count--; }