/// <summary> /// reates evaluation tree from postfix /// </summary> /// <param name="postfixNodes">postfix array</param> /// <returns>tree root node</returns> private LeafNode ToEvaluationTree(Node[] postfixNodes) { Stack stack = new Stack(); foreach (Node node in postfixNodes) { LeafNode ln; switch (node.Type) { case NodeType.Operand: // operand - only push to stack ln = new LeafNode(); ln.Data = node.Value; stack.Push(ln); break; case NodeType.Operator: // operator: setup left and right side and push to stack ln = new LeafNode(); ln.Data = node.Value; ln.Right = (LeafNode)stack.Pop(); ln.Left = (LeafNode)stack.Pop(); stack.Push(ln); break; } } if (stack.Count > 0) return (LeafNode)stack.Pop(); else return null; }
/// <summary> /// change to postfix layout /// </summary> /// <param name="infixNodes">infix array</param> /// <returns>postfix array</returns> private Node[] ToPostfix(Node[] infixNodes) { // temporary stack Stack stack = new Stack(); // output array ArrayList output = new ArrayList(); foreach (Node node in infixNodes) { switch (node.Type) { case NodeType.Operand: // add now output.Add(node); break; case NodeType.OpeningBracket: // add last from stack stack.Push(node); break; case NodeType.Operator: this.ProcessOperator(node, stack, output); break; case NodeType.ClosingBracket: this.StackToOutput(stack, output, true); break; } } // flush stack to output this.StackToOutput(stack, output, false); return (Node[])output.ToArray(typeof(Node)); }
/// <summary> /// process operator by type and priority /// </summary> /// <param name="node">operator</param> /// <param name="stack">stack of nodes</param> /// <param name="output">output arraylist</param> private void ProcessOperator(Node node, Stack stack, ArrayList output) { if (stack.Count == 0) // empty stack { // operator to stack stack.Push(node); } else { if (((Node)stack.Peek()).Type == NodeType.OpeningBracket) // there is opening bracked on top of stack { // operator to stack stack.Push(node); } else { if (node.Priority > ((Node)stack.Peek()).Priority) // operator has higher priority then last in stack // operator to stack stack.Push(node); else // operator has lower priority then last in stack { // last from stack to output output.Add(stack.Pop()); // recursive repeat this.ProcessOperator(node, stack, output); } } } }