This is because you have to keep the order of operations in mind when building the tree, Once the tree has been built in the correct order, its just a matter of doing a post-order traversal and evaluating as you go up the tree.
I kept thinking about how I should do this, and after talking to one of my friends, we realized that node rotations would be the simplest way to do it. So here is my code:
using System;
using System.Collections.Generic;
namespace Assignment5
{
public TreeNode<string> root;
public ExpressionTree(string input)
{
root = null;
ExpressionParser parser = new ExpressionParser(this, input);
}
private class ExpressionParser
{
private Stack<TreeNode<string>> numberStack, operatorStack;
public ExpressionParser(ExpressionTree tree, string input)
{
numberStack = new Stack<TreeNode<string>>();
operatorStack = new Stack<TreeNode<string>>();
string[] expressionArray = new string[input.Length];
expressionArray = input.Split();
BuildNodes(tree, expressionArray);
}
private void BuildNodes(ExpressionTree tree, string[] expressionArray)
{
foreach (string item in expressionArray)
{
double tempNumber;
if (double.TryParse(item, out tempNumber))
{
TreeNode<string> number_node = new TreeNode<string>
{ Data = tempNumber.ToString() };
numberStack.Push(number_node);
}
else
{
TreeNode<string> operator_node = new TreeNode<string>
{ Data = item };
operatorStack.Push(operator_node);
}
}
BuildTree(tree);
}
private void BuildTree(ExpressionTree tree)
{
while (operatorStack.Count != 0)
{
TreeNode<string> tempRoot = operatorStack.Pop();
tempRoot.Right = numberStack.Pop();
tempRoot.Left = numberStack.Pop();
if((tempRoot.Data == "*" || tempRoot.Data == "/") &&
(tempRoot.Right.Data == "+" || tempRoot.Right.Data == "-"))
{
tempRoot = tree.RotateLeft(tempRoot);
}
numberStack.Push(tempRoot);
}
TreeNode<string> subTree = numberStack.Pop();
tree.root = tree.RotateLeft(subTree);
}
}
private TreeNode<string> RotateLeft(TreeNode<string> currentNode)
{
TreeNode<string> tempNode = currentNode;
currentNode = currentNode.Right;
tempNode.Right = currentNode.Left;
currentNode.Left = tempNode;
return currentNode;
}
public void Evaluate(TreeNode<string> node)
{
if (node.Left != null)
Evaluate(node.Left);
if (node.Right != null)
Evaluate(node.Right);
switch (node.Data)
{
case "+":
double addResult = double.Parse(node.Left.Data) +
double.Parse(node.Right.Data);
node.Data = addResult.ToString();
node.Left = null;
node.Right = null;
break;
case "-":
double subResult = double.Parse(node.Left.Data) -
double.Parse(node.Right.Data);
node.Data = subResult.ToString();
node.Left = null;
node.Right = null;
break;
case "*":
double multResult = double.Parse(node.Left.Data) *
double.Parse(node.Right.Data);
node.Data = multResult.ToString();
node.Left = null;
node.Right = null;
break;
case "/":
double divResult = double.Parse(node.Left.Data) /
double.Parse(node.Right.Data);
node.Data = divResult.ToString();
node.Left = null;
node.Right = null;
break;
case "^":
double expResult = Math.Pow(double.Parse(node.Left.Data),
double.Parse(node.Right.Data));
node.Data = expResult.ToString();
node.Left = null;
node.Right = null;
break;
}
}
public string TraversePre(MyList<string> list, TreeNode<string> node)
{
list.Add(node.Data);
if (node.Left != null)
TraversePre(list, node.Left);
if (node.Right != null)
TraversePre(list, node.Right);
return string.Join(", ", list);
}
public string TraverseIn(MyList<string> list, TreeNode<string> node)
{
if (node.Left != null)
TraverseIn(list, node.Left);
list.Add(node.Data);
if (node.Right != null)
TraverseIn(list, node.Right);
return string.Join(", ", list);
}
public string TraversePost(MyList<string> list, TreeNode<string> node)
{
if (node.Left != null)
TraversePost(list, node.Left);
if (node.Right != null)
TraversePost(list, node.Right);
list.Add(node.Data);
return string.Join(", ", list);
}
}
}
I was not able to make my Binary Search Tree self balancing. I know what I need to do, but I never had time to actually implement the code. I will try to finish writing the code and post it here when I'm done with my AVL tree.
Anyways, that's all for now. Thanks for reading!
No comments:
Post a Comment