Binary tree traversal Inorder output is wrong why? - linked-list

Can someone explain why my output is wrong and how to fix it?
for example: i will input A B C D E
output is giving me A B C D E
insead of Inorder Traversal: D B E A C
this is my code:
int main()
{
struct node *root = NULL;
int choice, n; // item
char item;
do
{
printf("\n1. Insert Node");
printf("\n2. Traverse in Inorder");
printf("\nEnter Choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
root = NULL;
printf("\n\n Nodes : ");
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
printf("\nEnter data for node %d : ", i);
scanf(" %c",&item);
root = Create(root,item);
}
break;
case 2:
printf("\nBST Traversal in INORDER \n");
Inorder(root); break;
default:
printf("\n\nINVALID OPTION TRY AGAIN\n\n"); break;
}
} while(choice != 3);
}
struct node *Create(struct node *root, char item)
{
if(root == NULL)
{
root = (struct node *)malloc(sizeof(struct node));
root->left = root->right = NULL;
root->data = item;
return root;
}
else
{
if(item < root->data )
root->left = Create(root->left,item);
else if(item > root->data )
root->right = Create(root->right,item);
else
printf(" Duplicate Element !! Not Allowed !!!");
return(root);
}
}
void Inorder(struct node *root)
{
if( root != NULL)
{
Inorder(root->left);
printf(" %c ",root->data);
Inorder(root->right);
}
}
i doubled check the algorithm of The traversal Inorder but my output is still wrong i don't understand why? did i miss something here

The result is as expected. The in-order traversal should not produce D B E A C for your input of A B C D E
This is how the tree is constructed.
First the root is created with value A
Then B is inserted. As B > A, it is inserted as a right child of the root:
A
\
B
Then B is inserted. As C > A, it is inserted in the right subtree. There again we find C > B, so the new node will be inserted as a right child of B:
A
\
B
\
C
In the same way D and then E are inserted, giving this tree:
A
\
B
\
C
\
D
\
E
Note that this tree is not balanced at all. That's what happens when you insert nodes in their lexical order. If you would insert them in a more random order, we would expect the tree to be more balanced.
But it does not actually matter for the in-order traversal. What you have implemented is a binary search tree (BST). And one important property of BSTs is that their in-order traversal always produces the data in their right order. And so irrespective of the order in which you input the letters A B C D and E, the in-order traversal should always output this sequence:
A B C D E
This is correct.

Related

Generic type inference in function from lists

I'm working on some generic list utility functions and there seems to be an issue with the type inference for a generic function when the primary variables are lists. This is demonstrated with the following code:
List<T> combine<T>(List<T> a, List<T> b, T Function(T a, T b) combiner) {
final list = <T>[];
for (int i = 0; i < a.length && i < b.length; i++) {
list.add(combiner(a[i], b[i]));
}
return list;
}
void main() {
final a = [5, 8];
final b = [7, -3];
final c = combine(a, b, (a, b) => a + b); // Error
print(c);
// Expected: [12, 5]
}
When I use this code as-is, the type inference within the lambda sets a and b to be Object?, which results in the following error message:
The operator '+' can't be unconditionally invoked because the receiver can be 'null'.
Try adding a null check to the target ('!').
Doing what the error message says changes the message to the following:
The operator '+' isn't defined for the type 'Object'.
Try defining the operator '+'.
The issue obviously is that type inference is assigning the parameters to Object? instead of the expected int. This can be worked around by either typing the parameters or explicitly passing the generic type to the function:
final c = combine(a, b, (int a, int b) => a + b);
// OR
final c = combine<int>(a, b, (a, b) => a + b);
However, that's an added level of verbosity that I don't want to have to force the users of these utility functions to have to do (not to mention it will be a support issue when I have to explain to them to do this). Is there a way to change the function signature to make it so type inference works as expected?
This is basically Dart List.fold vs List.reduce type inference, but in your case you could sidestep the problem by making your function an extension method so that T is deduced from the receiver instead of from the arguments:
extension<T> on List<T> {
List<T> combineWith(List<T> b, T Function(T a, T b) combiner) {
final list = <T>[];
for (int i = 0; i < length && i < b.length; i++) {
list.add(combiner(this[i], b[i]));
}
return list;
}
}
void main() {
final a = [5, 8];
final b = [7, -3];
final c = a.combineWith(b, (a, b) => a + b); // Error
print(c);
// Expected: [12, 5]
}

Dart convert a string into a condition statement

I have some string conditions on my database, such as "==", "!=", ">", ">="... I want to use those conditions on my client side.
if (a myCondition b) print('ok')
How do I convert a string into an actual condition?
You will have to parse your string and perform the appropriate comparison manually. One way:
bool applyCondition(String comparison, dynamic a, dynamic b) {
switch (comparison) {
case '==':
return a == b;
case '!=':
return a != b;
case '>':
return a > b;
case '>=':
return a >= b;
// Other cases...
}
}
if (applyCondition(myCondition, a, b)) {
print('ok');
}
A slightly more compact (but likely less efficient) version with a Map instead of switch:
final comparatorTable = <String, bool Function(dynamic, dynamic)>{
'==': (a, b) => a == b,
'!=': (a, b) => a != b,
'>': (a, b) => a > b,
'>=': (a, b) => a >= b,
// Other cases...
};
if (comparatorTable[myCondition]!(a, b)) {
print('ok');
}

Building expression parser with Dart petitparser, getting stuck on node visitor

I've got more of my expression parser working (Dart PetitParser to get at AST datastructure created with ExpressionBuilder). It appears to be generating accurate ASTs for floats, parens, power, multiply, divide, add, subtract, unary negative in front of both numbers and expressions. (The nodes are either literal strings, or an object that has a precedence with a List payload that gets walked and concatenated.)
I'm stuck now on visiting the nodes. I have clean access to the top node (thanks to Lukas), but I'm stuck on deciding whether or not to add a paren. For example, in 20+30*40, we don't need parens around 30*40, and the parse tree correctly has the node for this closer to the root so I'll hit it first during traversal. However, I don't seem to have enough data when looking at the 30*40 node to determine if it needs parens before going on to the 20+.. A very similar case would be (20+30)*40, which gets parsed correctly with 20+30 closer to the root, so once again, when visiting the 20+30 node I need to add parens before going on to *40.
This has to be a solved problem, but I never went to compiler school, so I know just enough about ASTs to be dangerous. What "a ha" am I missing?
// rip-common.dart:
import 'package:petitparser/petitparser.dart';
// import 'package:petitparser/debug.dart';
class Node {
int precedence;
List<dynamic> args;
Node([this.precedence = 0, this.args = const []]) {
// nodeList.add(this);
}
#override
String toString() => 'Node($precedence $args)';
String visit([int fromPrecedence = -1]) {
print('=== visiting $this ===');
var buf = StringBuffer();
var parens = (precedence > 0) &&
(fromPrecedence > 0) &&
(precedence < fromPrecedence);
print('<$fromPrecedence $precedence $parens>');
// for debugging:
var curlyOpen = '';
var curlyClose = '';
buf.write(parens ? '(' : curlyOpen);
for (var arg in args) {
if (arg is Node) {
buf.write(arg.visit(precedence));
} else if (arg is String) {
buf.write(arg);
} else {
print('not Node or String: $arg');
buf.write('$arg');
}
}
buf.write(parens ? ')' : curlyClose);
print('$buf for buf');
return '$buf';
}
}
class RIPParser {
Parser _make_parser() {
final builder = ExpressionBuilder();
var number = char('-').optional() &
digit().plus() &
(char('.') & digit().plus()).optional();
// precedence 5
builder.group()
..primitive(number.flatten().map((a) => Node(0, [a])))
..wrapper(char('('), char(')'), (l, a, r) => Node(0, [a]));
// negation is a prefix operator
// precedence 4
builder.group()..prefix(char('-').trim(), (op, a) => Node(4, [op, a]));
// power is right-associative
// precedence 3
builder.group()..right(char('^').trim(), (a, op, b) => Node(3, [a, op, b]));
// multiplication and addition are left-associative
// precedence 2
builder.group()
..left(char('*').trim(), (a, op, b) => Node(2, [a, op, b]))
..left(char('/').trim(), (a, op, b) => Node(2, [a, op, b]));
// precedence 1
builder.group()
..left(char('+').trim(), (a, op, b) => Node(1, [a, op, b]))
..left(char('-').trim(), (a, op, b) => Node(1, [a, op, b]));
final parser = builder.build().end();
return parser;
}
Result _result(String input) {
var parser = _make_parser(); // eventually cache
var result = parser.parse(input);
return result;
}
String parse(String input) {
var result = _result(input);
if (result.isFailure) {
return result.message;
} else {
print('result.value = ${result.value}');
return '$result';
}
}
String visit(String input) {
var result = _result(input);
var top_node = result.value; // result.isFailure ...
return top_node.visit();
}
}
// rip_cmd_example.dart
import 'dart:io';
import 'package:rip_common/rip_common.dart';
void main() {
print('start');
String input;
while (true) {
input = stdin.readLineSync();
if (input.isEmpty) {
break;
}
print(RIPParser().parse(input));
print(RIPParser().visit(input));
}
;
print('done');
}
As you've observed, the ExpressionBuilder already assembles the tree in the right precedence order based on the operator groups you've specified.
This also happens for the wrapping parens node created here: ..wrapper(char('('), char(')'), (l, a, r) => Node(0, [a])). If I test for this node, I get back the input string for your example expressions: var parens = precedence == 0 && args.length == 1 && args[0] is Node;.
Unless I am missing something, there should be no reason for you to track the precedence manually. I would also recommend that you create different node classes for the different operators: ValueNode, ParensNode, NegNode, PowNode, MulNode, ... A bit verbose, but much easier to understand what is going on, if each of them can just visit (print, evaluate, optimize, ...) itself.

Clang IfStmt with shortcut binary operator in condition

I am trying to detect if there is a function call inside an if statement as part of condition; like following:
if (cmp(a, b)){
\\do something
}
I have found I could do this with AST matcher in following manner:
Matcher.addMatcher(ifStmt(hasCondition(callExpr().bind("call_expr")))
.bind("call_if_stmt"),&handleMatch);
But the problem is condition could have shortcuts like &&, ||; like following:
if(a != b && cmp(a,b) || c == 10){
\\ do something
}
Now this condition has binaryoperator && and ||; also have a call expression as part of it. Now how I could detect that there is a call expression inside this if statement? Definitely I don't know how many binary operator as shortcuts will be there, so I am looking for a generalize solution for this, possibly using clange AST matcher.
In the first case, if(cmp(a,b)), the CallExpr node is a direct child of the IfStmt. In the second case, it is a descendant of the IfStmt, but not a child. Instead, it is nested beneath two BinaryOperator nodes. (I found this out by looking at the AST with clang-check -ast-dump test.cpp --.) Adding a hasDescendant traversal matcher will find the more deeply nested CallExpr. Unfortunately, that alone will not find the first case. So we could use anyOf to combine it with the original matcher:
ifStmt(
hasCondition(
anyOf(
callExpr().bind("top_level_call_expr"),
hasDescendant(
callExpr().bind("nested_call_expr")
)
)
)
).bind("call_if_stmt")
If I take test.cpp to have the following code:
bool cmp(int a, int b){return a < b;}
int f(int a, int c){
int b = 42;
if( a != b && cmp(a,b) || c == 10){
return 2;
}
return c;
}
int g(int a, int c){
int b = 42;
if( cmp(a,b)) {
return 2;
}
return c;
}
then I can test this with clang-query test.cpp --:
clang-query> let m2 ifStmt( hasCondition( anyOf(callExpr().bind("top_level_call_expr"),hasDescendant(callExpr().bind("nested_call_expr"))))).bind("call_if_stmt")
clang-query> m m2
Match #1:
/path/to/test.xpp:5:7: note: "call_if_stmt" binds here
if( a != b && cmp(a,b) || c == 10){
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/path/to/test.cpp:5:21: note: "nested_call_expr" binds here
if( a != b && cmp(a,b) || c == 10){
^~~~~~~~
/path/to/test.cpp:5:7: note: "root" binds here
if( a != b && cmp(a,b) || c == 10){
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Match #2:
/path/to/test.cpp:13:7: note: "call_if_stmt" binds here
if( cmp(a,b)) {
^~~~~~~~~~~~~~~
/path/to/test.cpp:13:7: note: "root" binds here
if( cmp(a,b)) {
^~~~~~~~~~~~~~~
/path/to/test.cpp:13:11: note: "top_level_call_expr" binds here
if( cmp(a,b)) {
^~~~~~~~
2 matches.

How do you print the conditional statement of an IfStmt in Clang?

I'm developing a plugin for the clang compiler, and would like the conditional expressions of if statements in string form. That is, given:
if (a + b + c > 10)
return;
and a reference to the IfStmt node that represents it, I would like to obtain the string "a + b + c > 10".
I suspect that isn't possible, but if anybody has any insight, it would be greatly appreciated.
Extract the condition part of the IfStmt, take its start and end location and use this to query the lexer for the underlying source code.
using namespace clang;
class IfStmtVisitor
: public RecursiveASTVisitor<IfStmtVisitor> {
SourceManager &sm; // Initialize me!
CompilerInstance &ci; // Initialize me!
bool VisitIfStmt(IfStmt *stmt) {
Expr *expr = stmt->getCond();
bool invalid;
CharSourceRange conditionRange =
CharSourceRange::getTokenRange(expr->getLocStart(), expr->getLocEnd());
StringRef str =
Lexer::getSourceText(conditionRange, sm, ci.getLangOpts(), &invalid);
if (invalid) {
return false;
}
llvm::outs() << "Condition: " << str << "\n";
return true;
}
};
Input source:
bool f(int a, int b, int c)
{
if (a + b + c > 10)
return true;
return false;
}
Output:
Condition string: a + b + c > 10
I believe you may want to try looking at the printPretty function defined in Stmt which IfStmt inherits from. That should hopefully get you close to what you want.

Resources