public T Search(MyLineTreeNode <T> parent, int left, int right) { //如果完全相等,则直接返回保存的值 if (left == parent.StartIndex && right == parent.EndIndex) { return(parent.SavedVal); } //中间索引 int mid = (parent.StartIndex + parent.EndIndex) / 2; //如果要找的结束范围小于中间索引,在直接在节点左边树找 if (right <= mid) { return(Search(parent.Left, left, right)); } //如果要找的开始范围大于中间索引,在直接在节点右边树找 else if (left > mid) { return(Search(parent.Right, left, right)); } else { //否则两边都找 T leftObj = Search(parent.Left, left, mid); T rightObj = Search(parent.Right, mid + 1, right); return(CompareFunction.Invoke(leftObj, rightObj) ? leftObj : rightObj); } }
/// <summary> /// 更改节点值 /// </summary> /// <param name="index"></param> /// <param name="weight"></param> public void Change(int index, T val) { MyLineTreeNode <T> parent = Root; //通过循环找到索引所在的节点 do { int mid = (parent.StartIndex + parent.EndIndex) / 2; if (index <= mid) { parent = parent.Left; } else { parent = parent.Right; } } while (parent.StartIndex != index || parent.EndIndex != index); //更改所在节点的值 parent.SavedVal = val; //更改所在节点的值之后,需要调整所有父节点的值(通过不断和右边节点比较) while (parent.Parent != null) { MyLineTreeNode <T> temp = parent.Parent; temp.SavedVal = CompareFunction.Invoke(temp.Left.SavedVal, temp.Right.SavedVal) ? temp.Left.SavedVal : temp.Right.SavedVal; parent = temp; } }
/// <summary> /// 构造树 /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="ts"></param> /// <returns></returns> private MyLineTreeNode <T> BuildTree(int start, int end, T[] ts) { MyLineTreeNode <T> node = new MyLineTreeNode <T>(start, end, this.MaxValue, CompareFunction); if (start < end) { int mid = (start + end) / 2; MyLineTreeNode <T> left = BuildTree(start, mid, ts); left.Parent = node; node.Left = left; MyLineTreeNode <T> right = BuildTree(mid + 1, end, ts); right.Parent = node; node.Right = right; } if (start == end) { node.Left = null; node.Right = null; node.SavedVal = ts[start - 1]; } return(node); }