In my WPF 4.0 project, I have an ObservableCollection that contain some selected Visual3D from the view :
public ObservableCollection<Visual3D> SelectedElements
{
get { return _selectedElements; }
set
{
if (Equals(_selectedElements, value))
{
return;
}
_selectedElements = value;
RaisePropertyChanged(() => SelectedElements);
}
}
Visual3D elements are selected by clicking and the source-code in the VM is :
public HitTestResultBehavior HitTestDown(HitTestResult result)
{
var resultMesh = result as RayMeshGeometry3DHitTestResult;
if (resultMesh == null)
return HitTestResultBehavior.Continue;
// Obtain clicked ModelVisual3D.
var vis = resultMesh.VisualHit as ModelVisual3D;
if (vis != null)
{
Type visType = vis.GetType();
if (visType.Name == "TruncatedConeVisual3D" || visType.Name == "BoxVisual3D")
{
var geoModel = resultMesh.ModelHit as GeometryModel3D;
if (geoModel != null)
{
var selecteMat = geoModel.Material as DiffuseMaterial;
if (selecteMat != null) selecteMat.Brush.Opacity = selecteMat.Brush.Opacity <= 0.7 ? 1 : 0.7;
}
// Otherwise it's a chair. Get the Transform3DGroup.
var xformgrp = vis.Transform as Transform3DGroup;
// This should not happen, but play it safe anyway.
if (xformgrp == null)
{
return HitTestResultBehavior.Stop;
}
// Loop through the child tranforms.
foreach (Transform3D t in xformgrp.Children)
{
// Find the TranslateTransform3D.
var trans =
t as TranslateTransform3D;
if (trans != null)
{
// Define an animation for the transform.
var anima = new DoubleAnimation();
if (trans.OffsetY == 0)
{
DependencyProperty prop = TranslateTransform3D.OffsetZProperty;
if (Math.Abs(trans.OffsetZ) < 2)
{
anima.To = 20.5*Math.Sign(trans.OffsetZ);
Debug.Assert(SelectedElements != null, "SelectedElements != null");
}
else
{
anima.To = 1*Math.Sign(trans.OffsetZ);
SelectedElements.Add(vis);
}
// Start the animation and stop the hit-testing.
trans.BeginAnimation(prop, anima);
return HitTestResultBehavior.Stop;
}
}
}
}
}
return (HitTestResultBehavior) HitTestFilterBehavior.Continue;
}
and I want to delete one or all this Visual3D element
Thank you in advance
I have implemented this methode but it's not work :
private void UnloadProduct()
{
if (CanUnload)
{
foreach (Visual3D selectedElement in SelectedElements)
{
if (selectedElement.DependencyObjectType.Name == "TruncatedConeVisual3D")
{
var test = (TruncatedConeVisual3D) selectedElement;
int id = test.VisualId;
ElementsCollection.RemoveAt(id);
RaisePropertyChanged(() => ElementsCollection);
}
else
{
var test = (BoxVisual3D) selectedElement;
int id = test.VisualId;
ProductsCollection.RemoveAt(id);
}
}
}
}
Related
I'm trying to create a function InsertInOrder() that inserts an item in the correct place without disturbing the order.
Ex:
LinkedList before [3,5,6] after inserting 4 ---> [3,4,5,6].
I have created the function but some reason it's not working as expected.
I'm testing the code on a Windows form application by entering ISBNs,
What went wrong:
First I inserted 23, then I inserted 10, expecting to be placed before 23 but here's what happened (image below):
What went wrong
Please find the code below:
LinkListGen Class
class LinkListGen<T> where T : IComparable
{
private LinkGen<T> list;
public LinkListGen()
{
list = null;
}
public void AddItem(T item)
{
list = new LinkGen<T>(item, list); //create a new link on the front of the list
}
public void AppendItem(T item)
{
LinkGen<T> temp = list;
if (temp == null)
{
list = new LinkGen<T>(item);
}
else
{
while (temp.Next != null)
{
temp = temp.Next;
}
temp.Next = new LinkGen<T>(item);
}
}
public string DisplayList()
{
string buffer = "";
LinkGen<T> temp = list; //temp starts beginning of list
while (temp != null) //not at end of list
{
buffer = buffer + temp.Data.ToString() + ",";
temp = temp.Next; //move along a link
}
return buffer;
}
public void RemoveItem(T item)
{
LinkGen<T> temp = list;
LinkListGen<T> newList = new LinkListGen<T>();
while (temp != null)
{
if (item.CompareTo(temp.Data) != 0)
{
newList.AppendItem(temp.Data);
}
temp = temp.Next;
}
list = newList.list;
}
public void InsertInOrder (T item)
{
LinkGen<T> temp = list;
LinkListGen<T> newList = new LinkListGen<T>();
if (list == null)
{
AppendItem(item);
}
else
{
while (temp != null)
{
if(list.Data.CompareTo(item) < 0)
{
newList.AppendItem(list.Data);
temp = temp.Next;
}
else if(list.Data.CompareTo(item) > 0)
{
newList.AppendItem(item);
newList.AppendItem(list.Data);
temp = temp.Next;
}
newList.AppendItem(list.Data);
temp = temp.Next;
}
}
}
}
Windows Form App code
public partial class Form1 : Form
{
LinkListGen<Book> ISBNList = new LinkListGen<Book>();
public Form1()
{
InitializeComponent();
}
private void AddButton_Click(object sender, EventArgs e)
{
double insertedISBN = Convert.ToDouble(ISBNTextBox.Text);
Book newBook = new Book(insertedISBN);
ISBNList.InsertInOrder(newBook);
DisplayLabel.Text = ISBNList.DisplayList();
}
private void RemoveButton_Click(object sender, EventArgs e)
{
double insertedISBN = Convert.ToDouble(ISBNTextBox.Text);
Book removeBook = new Book(insertedISBN);
ISBNList.RemoveItem(removeBook);
DisplayLabel.Text = ISBNList.DisplayList();
}
}
Your problem, that you call AppendItem at InsertInOrder, which adds element to the end of the list, instead pure pointer manipulation.
At the same time, you shouldn't recreate list at InsertInOrder to avoid memory/time overhead.
Try next code, not tested:
public void InsertInOrder(T item)
{
var node = new LinkGen<T>(item);
if (list == null)
{
list = node;
return;
}
var current = list;
while (current != null)
{
if (current.Data.CompareTo(item) < 0)
{
// current is last element
if (current.Next == null)
{
current.Next = node;
break;
}
// current.Next.Data is equal or greater than new value
// so set new node.Next to current.Next and current.Next to new node
if (current.Next.Data.CompareTo(item) >= 0)
{
node.Next = current.Next;
current.Next = node;
break;
}
}
current = current.Next;
}
}
I am trying to write the remove function for BST in C#. I have some NUnit tests that need to pass. All of them pass except two. I have two scenarios for which the test fails.
I need to remove 10 for these two trees. But it's failing:
100, 10, 5
100, 10, 20
So I'm guessing my code doesn't splice the 10 out. And the error is in the RemoveNonRootNode method. And specifically with the "else if" statements that are looking at 1 child situation.
Here is my code. I appreciate some help!
public class BST
{
private BSTNode m_top;
private class BSTNode
{
private int m_data;
private BSTNode m_left;
private BSTNode m_right;
public int Data
{
get { return m_data; }
set { m_data = value; }
}
public BSTNode Left
{
get { return m_left; }
set { m_left = value; }
}
public BSTNode Right
{
get { return m_right; }
set { m_right = value; }
}
public BSTNode(int data)
{
m_data = data;
}
}
public void AddValue(int v)
{
if (m_top == null)
{
m_top = new BSTNode(v);
}
else
{
BSTNode cur = m_top;
while (true)
{
if (v < cur.Data)
{
if (cur.Left == null)
{
cur.Left = new BSTNode(v);
return;
}
else
cur = cur.Left;
}
else if (v > cur.Data)
{
if (cur.Right == null)
{
cur.Right = new BSTNode(v);
return;
}
else
cur = cur.Right;
}
else
throw new DuplicateValueException("Value " + v + " is already in the tree!");
}
}
}
public void Print()
{
Console.WriteLine("=== Printing the tree ===");
if (m_top == null)
Console.WriteLine("Empty tree!");
else
PrintInternal(m_top);
}
private void PrintInternal(BSTNode cur)
{
if (cur.Left != null)
PrintInternal(cur.Left);
Console.WriteLine(cur.Data);
if (cur.Right != null)
PrintInternal(cur.Right);
}
public bool Find(int target)
{
return FindNode(target) != null;
}
private BSTNode FindNode(int target)
{
BSTNode cur = m_top;
while (cur != null)
{
if (cur.Data == target)
return cur;
else if (target < cur.Data)
cur = cur.Left;
else if (target > cur.Data)
cur = cur.Right;
}
return null;
}
public void Remove(int target)
{
// if the tree is empty:
if (m_top == null)
return;
if (m_top.Data == target)
{
RemoveRootNode(target);
}
else
{
RemoveNonrootNode(target);
}
}
private void RemoveNonrootNode(int target)
{
BSTNode cur = m_top;
BSTNode parent = null;
//First, find the target node that we need to remove
// we'll have the 'parent' reference trail the cur pointer down the tree
// so when we stop, cur is the node to remove, and parent is one above it.
while (cur!= null && cur.Data != target)
{
parent = cur;
if (target > cur.Data)
cur = cur.Right;
else
cur = cur.Left;
}
// Next, we figure out which of the cases we're in
// Case 1: The target node has no children
if (cur.Left == null && cur.Right == null)
{
if (parent.Left==cur)
parent.Left = null;
else
parent.Right = null;
}
// Case 2: The target node has 1 child
// (You may want to split out the left vs. right child thing)
else if (cur.Left == null)
{
BSTNode cur2 = cur;
cur = cur.Right;
cur2 = null;
return;
}
else if (cur.Right == null)
{
BSTNode cur2 = cur;
cur = cur.Right;
cur2 = null;
return;
}
// Case 3: The target node has 2 children
BSTNode removee = FindAndRemoveNextSmallerValue(target, cur);
cur.Data = removee.Data;
return;
}
private void RemoveRootNode(int target)
{
// If we're here, it's because we're removing the top-most node (the 'root' node)
// Case 1: Root has no children
if (m_top.Left == null && m_top.Right == null)
{
m_top = null; // Therefore, the tree is now empty
return;
}
// Case 2: Root has 1 child
else if (m_top.Left == null)
{
// 1 (right) child, OR zero children (right may also be null)
m_top = m_top.Right; // Right is null or another node - either way is correct
return;
}
else if (m_top.Right == null)
{
// If we're here, Left is not null, so there MUST be one (Left) Child
m_top = m_top.Left;
return;
}
// Case 3: Root has two children - this is where it gets interesting :)
else
{
// 2 children - find (and remove) next smaller value
// use that data to overwrite the current data.
BSTNode removee = FindAndRemoveNextSmallerValue(target, m_top);
m_top.Data = removee.Data;
return;
}
}
/// <summary>
/// This method takes 1 step to the left, then walks as far to the right
/// as possible. Once that right-most node is found, it's removed & returned.
/// Note that the node MAY be immediately to the left of the <B>startHere</B>
/// parameter, if startHere.Left.Right == null
/// </summary>
/// <param name="smallerThanThis"></param>
/// <param name="startHere"></param>
/// <returns></returns>
private BSTNode FindAndRemoveNextSmallerValue(int smallerThanThis, BSTNode startHere)
{
BSTNode parent = startHere;
BSTNode child = startHere.Left;
if (child.Data == smallerThanThis)
{
child = null;
}
while (child.Right != null)
{
parent = child;
child = child.Right;
}
parent = child;
child = null;
return parent;
}
// Given the value of a node, find (and remove) the predessor node in the tree
// returns the value of the predecessor node, or Int32.MinValue if no such value was found
public int TestFindAndRemoveNextSmallest(int sourceNode)
{
BSTNode startAt = this.FindNode(sourceNode);
// sourceNode should == startAt.Data, unless startAt is null)
BSTNode removed = FindAndRemoveNextSmallerValue(sourceNode, startAt);
if (removed != null)
return removed.Data;
else
return Int32.MinValue;
}
}
At first sight, there seems to be this bug:
else if (cur.Left == null)
{
BSTNode cur2 = cur;
cur = cur.Right;
cur2 = null;
return;
}
else if (cur.Right == null)
{
BSTNode cur2 = cur;
// cur = cur.Right; // THIS SHOULD BE .Left, because .Right is NULL
cur = cur.Left; // THIS IS THE FIX
cur2 = null;
return;
}
But your actual problem is; updating the cur reference to something else does not change the pointer to the same object (cur) held by its parent. Actually, you did it right in Case 1, but somehow missed it in Case 2. Therefore; the full fix is: (only fixing the failing test. Promising no more).
// Case 2: The target node has 1 child
// (You may want to split out the left vs. right child thing)
else if (cur.Left == null)
{
if (parent.Left == cur)
{
parent.Left = cur.Right;
}
else
{
parent.Right = cur.Right;
}
return;
}
else if (cur.Right == null)
{
if(parent.Left == cur)
{
parent.Left = cur.Left;
}
else
{
parent.Right = cur.Left;
}
return;
}
I have an XF application using BottomNavigationView in Android side that removes and add TabbedPage children depending on the user mode. Below is my Android renderer:
public class BottomTabPageRenderer : TabbedPageRenderer
{
public BottomTabPageRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (ViewGroup != null && ViewGroup.ChildCount > 0)
{
BottomNavigationMenuView bottomNavigationMenuView = FindChildOfType<BottomNavigationMenuView>(ViewGroup);
if (bottomNavigationMenuView != null)
{
var shiftMode = bottomNavigationMenuView.Class.GetDeclaredField("mShiftingMode");
shiftMode.Accessible = true;
shiftMode.SetBoolean(bottomNavigationMenuView, false);
shiftMode.Accessible = false;
shiftMode.Dispose();
for (var i = 0; i < bottomNavigationMenuView.ChildCount; i++)
{
var item = bottomNavigationMenuView.GetChildAt(i) as BottomNavigationItemView;
if (item == null) continue;
item.SetShiftingMode(false);
item.SetChecked(item.ItemData.IsChecked);
}
if (bottomNavigationMenuView.ChildCount > 0) bottomNavigationMenuView.UpdateMenuView();
}
}
T FindChildOfType<T>(ViewGroup viewGroup) where T : Android.Views.View
{
if (viewGroup == null || viewGroup.ChildCount == 0) return null;
for (var i = 0; i < viewGroup.ChildCount; i++)
{
var child = viewGroup.GetChildAt(i);
var typedChild = child as T;
if (typedChild != null) return typedChild;
if (!(child is ViewGroup)) continue;
var result = FindChildOfType<T>(child as ViewGroup);
if (result != null) return result;
}
return null;
}
}
}
When the user starts the game by clicking a button, 4 out of 5 tabs at the bottom are removed. And when the user ends the game again by clicking a button the tabs are added again. I tried xxx.Children.Insert() to put the tabs back to their original position but this gives me the following errors:
Java.Lang.IndexOutOfBoundsException: Index: 1, Size: 1
So I ended up with the following code:
public static void ReAddChildren()
{
mainPage.Children.Remove(gameTabPage);
mainPage.Children.Add(homeTabPage);
mainPage.Children.Add(helpTabPage);
mainPage.Children.Add(settingsTabPage);
mainPage.Children.Add(dictTabPage);
mainPage.Children.Add(gameTabPage);
}
This works but now the shiftingMode is back. Anyone knows how I can disable this whenever I "re-add" the tab items?
Android just update it on 28.0.0 support library.
Not sure if Xamarin could access to this native method setLabelVisibilityMode() to disable the shifting or not.
navBottom.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
In renderer you can easily use this extension method from Xamarin.Forms to manage shift mode.
https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/BottomNavigationViewUtils.cs
so you would get:
using static Xamarin.Forms.Platform.Android.BottomNavigationViewUtils;
public class BottomTabPageRenderer : TabbedPageRenderer
{
public BottomTabPageRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (ViewGroup != null && ViewGroup.ChildCount > 0)
{
BottomNavigationMenuView bottomNavigationMenuView = FindChildOfType<BottomNavigationMenuView>(ViewGroup);
if (bottomNavigationMenuView != null)
{
// use extension method from XF
bottomNavigationMenuView.SetShiftMode(false, false);
}
}
T FindChildOfType<T>(ViewGroup viewGroup) where T : Android.Views.View
{
if (viewGroup == null || viewGroup.ChildCount == 0) return null;
for (var i = 0; i < viewGroup.ChildCount; i++)
{
var child = viewGroup.GetChildAt(i);
var typedChild = child as T;
if (typedChild != null) return typedChild;
if (!(child is ViewGroup)) continue;
var result = FindChildOfType<T>(child as ViewGroup);
if (result != null) return result;
}
return null;
}
}
}
As was mentioned from Pawel, you can easily use the extension method from Xamarin.Forms to manage shift mode. But this one was that worked for me
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
public CustomTabbedPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (ViewGroup != null && ViewGroup.ChildCount > 0)
{
BottomNavigationView bottomNavigationView = FindChildOfType<BottomNavigationView>(ViewGroup);
if (bottomNavigationView != null)
{
// use extension method from XF
bottomNavigationView.SetShiftMode(false, false);
}
}
}
private T FindChildOfType<T>(ViewGroup viewGroup) where T : Android.Views.View
{
if (viewGroup == null || viewGroup.ChildCount == 0) return null;
for (var i = 0; i < viewGroup.ChildCount; i++)
{
var child = viewGroup.GetChildAt(i);
var typedChild = child as T;
if (typedChild != null) return typedChild;
if (!(child is ViewGroup)) continue;
var result = FindChildOfType<T>(child as ViewGroup);
if (result != null) return result;
}
return null;
}
protected override void DispatchDraw(Canvas canvas)
{
base.DispatchDraw(canvas);
}
}
if (!string.IsNullOrEmpty(View.Panel1.ToString()))
{
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.PAN1 = View.Panel1;
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
if (!string.IsNullOrEmpty(View.Panel2.ToString()))
{
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.PAN2 = View.Panel2;
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
if (!string.IsNullOrEmpty(View.Panel3.ToString()))
{
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.PAN3 = View.Panel3;
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
if (!string.IsNullOrEmpty(View.Panel4.ToString()))
{
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.PAN4 = View.Panel4;
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
if (!string.IsNullOrEmpty(View.Panel5.ToString()))
{
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.PAN5 = View.Panel5;
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
.....
.....
I have a foreach loop like above and i'm repeating the same code inorder to pass each panel value.
I'm trying to reduce the repeated code like below( but not sure it is correct way )
if (!string.IsNullOrEmpty(View.Panel1.ToString()))
{
setpanelinfo(View.Panel1.ToString(),PAN1)
}
if (!string.IsNullOrEmpty(View.Panel2.ToString()))
{
setpanelinfo(View.Panel2.ToString(),PAN2)
}
....
....
....
public void setpanelinfo(string strpanelvalue, string PAN)
{
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.+ "PAN1" = strpanelvalue; // ERROR
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
Is there a better way to write this above foreach logic with minimal code?
One approach to simplifying this is to use an Action callback for each specific case:
void HandlePanel(string panel, Action<OtherFeatures> action)
{
if (!string.IsNullOrEmpty(panel))
{
foreach (var of in FeaturesInfo)
{
if (of != null)
{
action(of);
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
}
}
...
HandlePanel(View.Panel1.ToString(), of => of.PAN1 = View.Panel1);
HandlePanel(View.Panel2.ToString(), of => of.PAN2 = View.Panel2);
HandlePanel(View.Panel3.ToString(), of => of.PAN3 = View.Panel3);
HandlePanel(View.Panel4.ToString(), of => of.PAN4 = View.Panel4);
....
Use the Controls collection of the form object:
(typecast)Controls(of+"PAN1").SomeProperty = some value;
I just think foreach-ing the collection three times is a little wasteful. Maybe something like this might be a little more performant
foreach (var of in FeaturesInfo)
{
if (of != null)
{
TestAndSet(View.Panel1.ToString(), text => of.PAN1 = text);
TestAndSet(View.Panel2.ToString(), text => of.PAN2 = text);
TestAndSet(View.Panel3.ToString(), text => of.PAN3 = text);
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
break;
}
}
....
private void TestAndSet(String panel, Action<string> setAction)
{
if (!string.IsNullOrEmpty(panel))
{
setAction(panel);
}
}
In your case, you can do only one foreach and move the test inside of the loop.
foreach (OtherFeatures of in FeaturesInfo)
{
if (of != null)
{
of.NumOtherFeatures = null;
of.OtherFeaturesDesc = null;
if (!string.IsNullOrEmpty(View.Panel1.ToString()))
of.PAN1 = View.Panel1;
if (!string.IsNullOrEmpty(View.Panel2.ToString()))
of.PAN2 = View.Panel2;
if (!string.IsNullOrEmpty(View.Panel3.ToString()))
of.PAN3 = View.Panel3;
if (!string.IsNullOrEmpty(View.Panel4.ToString()))
of.PAN4 = View.Panel4;
if (!string.IsNullOrEmpty(View.Panel5.ToString()))
of.PAN5 = View.Panel5;
break;
}
}
I made a Tree Data Structure and I want the Elements to sort like this:
10
/ \
5 12
/ \ / \
3 7 11 18
If the value of the added element is smaller than the value of the other element, it should be linked left, and if bigger, right. My problem is, that I just can't get the sorting method right.
class Tree
{
private class TElement
{
public int _value;
public TElement _left;
public TElement _right;
public TElement(int value)
{
_value = value;
}
}
private TElement RootElement;
public void Add(int value)
{
TElement newElement = new TElement(value);
TElement current = new TElement(value);
current = RootElement;
if (RootElement == null)
{
RootElement = newElement;
return;
}
SortNewElement(RootElement, RootElement, newElement, RootElement);
}
private void SortNewElement(TElement left, TElement right, TElement newElement, TElement RootElement)
{
if (newElement._value < RootElement._value && RootElement._left == null)
{
left._left = newElement;
return;
}
if (newElement._value > RootElement._value && RootElement._right == null)
{
right._right = newElement;
return;
}
if (newElement._value < left._value && left._left == null)
{
left._left = newElement;
return;
}
if (newElement._value > right._value && right._right == null)
{
right._right = newElement;
return;
}
SortNewElement(left._left, right._right, newElement, RootElement);
}
}
I know it doesn't work because it's trying to get the linked nodes of a null element.
From what i can understand from your question you are just trying to insert a new node in a binary search tree. Its inorder traversal will be a sorted array.
You can do so by the following simple pseudo code
insert_new( Node* node, value)
{
if(value > node->value)
{
if(node->right != null)
{
insert_new(node->right,value);
}
else
{
node->right = new Node(value);
return;
}
}
else
{
if(node->left != null)
{
insert_new(node->left,value)
}
else
{
node->left = new Node(value);
return;
}
}
}
class element{
public:
int value;
*element left;
*element right;
element(int value)
value = value;
public add(&element a)
if (a != null)
{
if (left!=null){
left = a;
}
else{
if (left.value > a.value){
right = left;
left= a;
}
else{
right=a;
}
}