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