Unbalanced Binary Search Tree insertion and search with random and sorted values
up vote
0
down vote
favorite
I have created this unbalanced binary search tree in C. Can anyone say this is a true approach or not? I have two scenarios for insertion and search: in the first scenario I am inserting 10000 random values to tree, and in the second scenario I am inserting 10000 sorted values from 1 to 10000.
Am I on the right track?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
struct BSTNode {
int data;
struct BSTNode *BSTLeft;
struct BSTNode *BSTRight;
};
typedef struct BSTNode node;
node *rootNode= NULL;
void BSTInsert(int i, node **n) {
if (*n == NULL) {
(*n) = (node*)malloc(sizeof(node));
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
else if (i > (*n)->data)
BSTInsert(i, &((*n)->BSTRight));
else
BSTInsert(i, &((*n)->BSTLeft));
}
void BSTSearch(int i, node **n) {
if (*n == NULL)
printf("nValue does not exist in tree!");
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
BSTSearch(i, &((*n)->BSTRight));
else
BSTSearch(i, &((*n)->BSTLeft));
}
void test_scenario1() {
node *rootNode = NULL;
const int SIZE = 10000;
int *a = malloc(sizeof (int)*SIZE);
clock_t start, end;
for (int i = 1; i < SIZE; i++)
{
srand(time(NULL));
a[i] = rand() % 1000;
}
printf("Inserting values to BST with %d random nodes...n", SIZE);
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTInsert(a[i], &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with random Values
printf("Searching random values in BST...");
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTSearch(a[i], &rootNode);
}
end = clock();
printf("nDone. Took %.8f secondsn", (double) (end - start) / CLOCKS_PER_SEC);
free(a);
}
void test_scenario2(){
node *rootNode = NULL;
const int SIZE = 10000;
clock_t start, end;
int num;
printf("nInserting values to BST with %d sorted nodes...n", SIZE);
start = clock();
for (num=1;num<=10000;num++){
BSTInsert(num, &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with sorted Values
printf("Searching sorted values in BST...");
start = clock();
for (num=1;num<=10000;num++)
BSTSearch(num, &rootNode);
end = clock();
printf("nDone. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
}
// Main function for these three scenarios.
int main(int argc, char ** argv)
{
test_scenario1();
test_scenario2();
}
performance c tree complexity
New contributor
add a comment |
up vote
0
down vote
favorite
I have created this unbalanced binary search tree in C. Can anyone say this is a true approach or not? I have two scenarios for insertion and search: in the first scenario I am inserting 10000 random values to tree, and in the second scenario I am inserting 10000 sorted values from 1 to 10000.
Am I on the right track?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
struct BSTNode {
int data;
struct BSTNode *BSTLeft;
struct BSTNode *BSTRight;
};
typedef struct BSTNode node;
node *rootNode= NULL;
void BSTInsert(int i, node **n) {
if (*n == NULL) {
(*n) = (node*)malloc(sizeof(node));
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
else if (i > (*n)->data)
BSTInsert(i, &((*n)->BSTRight));
else
BSTInsert(i, &((*n)->BSTLeft));
}
void BSTSearch(int i, node **n) {
if (*n == NULL)
printf("nValue does not exist in tree!");
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
BSTSearch(i, &((*n)->BSTRight));
else
BSTSearch(i, &((*n)->BSTLeft));
}
void test_scenario1() {
node *rootNode = NULL;
const int SIZE = 10000;
int *a = malloc(sizeof (int)*SIZE);
clock_t start, end;
for (int i = 1; i < SIZE; i++)
{
srand(time(NULL));
a[i] = rand() % 1000;
}
printf("Inserting values to BST with %d random nodes...n", SIZE);
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTInsert(a[i], &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with random Values
printf("Searching random values in BST...");
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTSearch(a[i], &rootNode);
}
end = clock();
printf("nDone. Took %.8f secondsn", (double) (end - start) / CLOCKS_PER_SEC);
free(a);
}
void test_scenario2(){
node *rootNode = NULL;
const int SIZE = 10000;
clock_t start, end;
int num;
printf("nInserting values to BST with %d sorted nodes...n", SIZE);
start = clock();
for (num=1;num<=10000;num++){
BSTInsert(num, &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with sorted Values
printf("Searching sorted values in BST...");
start = clock();
for (num=1;num<=10000;num++)
BSTSearch(num, &rootNode);
end = clock();
printf("nDone. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
}
// Main function for these three scenarios.
int main(int argc, char ** argv)
{
test_scenario1();
test_scenario2();
}
performance c tree complexity
New contributor
Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have created this unbalanced binary search tree in C. Can anyone say this is a true approach or not? I have two scenarios for insertion and search: in the first scenario I am inserting 10000 random values to tree, and in the second scenario I am inserting 10000 sorted values from 1 to 10000.
Am I on the right track?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
struct BSTNode {
int data;
struct BSTNode *BSTLeft;
struct BSTNode *BSTRight;
};
typedef struct BSTNode node;
node *rootNode= NULL;
void BSTInsert(int i, node **n) {
if (*n == NULL) {
(*n) = (node*)malloc(sizeof(node));
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
else if (i > (*n)->data)
BSTInsert(i, &((*n)->BSTRight));
else
BSTInsert(i, &((*n)->BSTLeft));
}
void BSTSearch(int i, node **n) {
if (*n == NULL)
printf("nValue does not exist in tree!");
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
BSTSearch(i, &((*n)->BSTRight));
else
BSTSearch(i, &((*n)->BSTLeft));
}
void test_scenario1() {
node *rootNode = NULL;
const int SIZE = 10000;
int *a = malloc(sizeof (int)*SIZE);
clock_t start, end;
for (int i = 1; i < SIZE; i++)
{
srand(time(NULL));
a[i] = rand() % 1000;
}
printf("Inserting values to BST with %d random nodes...n", SIZE);
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTInsert(a[i], &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with random Values
printf("Searching random values in BST...");
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTSearch(a[i], &rootNode);
}
end = clock();
printf("nDone. Took %.8f secondsn", (double) (end - start) / CLOCKS_PER_SEC);
free(a);
}
void test_scenario2(){
node *rootNode = NULL;
const int SIZE = 10000;
clock_t start, end;
int num;
printf("nInserting values to BST with %d sorted nodes...n", SIZE);
start = clock();
for (num=1;num<=10000;num++){
BSTInsert(num, &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with sorted Values
printf("Searching sorted values in BST...");
start = clock();
for (num=1;num<=10000;num++)
BSTSearch(num, &rootNode);
end = clock();
printf("nDone. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
}
// Main function for these three scenarios.
int main(int argc, char ** argv)
{
test_scenario1();
test_scenario2();
}
performance c tree complexity
New contributor
I have created this unbalanced binary search tree in C. Can anyone say this is a true approach or not? I have two scenarios for insertion and search: in the first scenario I am inserting 10000 random values to tree, and in the second scenario I am inserting 10000 sorted values from 1 to 10000.
Am I on the right track?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
struct BSTNode {
int data;
struct BSTNode *BSTLeft;
struct BSTNode *BSTRight;
};
typedef struct BSTNode node;
node *rootNode= NULL;
void BSTInsert(int i, node **n) {
if (*n == NULL) {
(*n) = (node*)malloc(sizeof(node));
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
else if (i > (*n)->data)
BSTInsert(i, &((*n)->BSTRight));
else
BSTInsert(i, &((*n)->BSTLeft));
}
void BSTSearch(int i, node **n) {
if (*n == NULL)
printf("nValue does not exist in tree!");
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
BSTSearch(i, &((*n)->BSTRight));
else
BSTSearch(i, &((*n)->BSTLeft));
}
void test_scenario1() {
node *rootNode = NULL;
const int SIZE = 10000;
int *a = malloc(sizeof (int)*SIZE);
clock_t start, end;
for (int i = 1; i < SIZE; i++)
{
srand(time(NULL));
a[i] = rand() % 1000;
}
printf("Inserting values to BST with %d random nodes...n", SIZE);
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTInsert(a[i], &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with random Values
printf("Searching random values in BST...");
start = clock();
for (int i = 0; i < SIZE; i++) {
BSTSearch(a[i], &rootNode);
}
end = clock();
printf("nDone. Took %.8f secondsn", (double) (end - start) / CLOCKS_PER_SEC);
free(a);
}
void test_scenario2(){
node *rootNode = NULL;
const int SIZE = 10000;
clock_t start, end;
int num;
printf("nInserting values to BST with %d sorted nodes...n", SIZE);
start = clock();
for (num=1;num<=10000;num++){
BSTInsert(num, &rootNode);
}
end = clock();
printf("Done. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
// Search in BST with sorted Values
printf("Searching sorted values in BST...");
start = clock();
for (num=1;num<=10000;num++)
BSTSearch(num, &rootNode);
end = clock();
printf("nDone. Took %.8f secondsnn", (double) (end - start) / CLOCKS_PER_SEC);
}
// Main function for these three scenarios.
int main(int argc, char ** argv)
{
test_scenario1();
test_scenario2();
}
performance c tree complexity
performance c tree complexity
New contributor
New contributor
edited yesterday
Sᴀᴍ Onᴇᴌᴀ
8,04061751
8,04061751
New contributor
asked yesterday
Hefaz
33
33
New contributor
New contributor
Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday
add a comment |
Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday
Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday
Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday
add a comment |
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
The global variable rootNode
is never used, and is confusing due to similar local variables, so remove it.
As we're ignoring all command-line arguments, we can use the simpler signature for main()
:
int main(void)
Prefer to use unsigned types for counting:
const unsigned int SIZE = 10000;
...
for (unsigned int i = 1; i < SIZE; ++i)
That addresses most of the compiler warnings I get for this code. The remaining warning is best eliminated with a cast to indicate that we don't care about preserving the correct value in this signed → unsigned conversion:
srand((unsigned)time(NULL));
Prefer to use the size of the variable than of its type when allocating memory. This makes it easier for reviewers to confirm that the sizes match:
if (!*n) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
and
int *a = malloc(sizeof *a * SIZE);
Use a memory checker; at the moment, we leak the entire BST:
Inserting values to BST with 10000 random nodes...
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x1091FC: BSTInsert (209085.c:24)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Done. Took 3.30890200 seconds
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10926D: BSTSearch (209085.c:33)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10927B: BSTSearch (209085.c:35)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Searching random values in BST...
Done. Took 0.00558500 seconds
Inserting values to BST with 10000 sorted nodes...
Done. Took 3.36596000 seconds
Searching sorted values in BST...
Done. Took 3.96642300 seconds
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x1094AA: test_scenario2 (209085.c:79)
==12434== by 0x109579: main (209085.c:97)
==12434==
Those early reports of using uninitialised values are certainly worth investigating, too.
Try to be consistent where that helps readers. Consider this fragment:
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
See how it's easier to see the relation between the two tests if we write the operands in the same order:
else if (i == (*n)->data)
return;
else if (i > (*n)->data)
Use the standard error stream for error messages:
if (*n == NULL)
fprintf(stderr, "Value does not exist in tree!n");
And prefer to write complete lines to output (especially relevant when it's connected to line-buffered devices, such as terminals and terminal-emulators).
Consider using more braces to enclose conditional commands. It's easier to avoid silly mistakes:
if (*n == NULL) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
} else if (i > (*n)->data) {
BSTInsert(i, &((*n)->BSTRight));
} else {
BSTInsert(i, &((*n)->BSTLeft));
}
We could make that code a lot clearer by copying *n
into a local variable:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
On the other hand, in the search function, we don't need to pass by pointer, and we can use const
. We probably ought to return something, too:
const int *BSTSearch(int i, const node *n) {
if (n == NULL) {
fprintf(stderr, "Value does not exist in tree!n");
return NULL;
} else if (i == n->data) {
return &n->data;
} else if (i > n->data) {
return BSTSearch(i, n->BSTRight);
} else {
return BSTSearch(i, n->BSTLeft);
}
}
Obviously, the call sites would then need to pass rootNode
by value, rather than &rootNode
pointer.
The parallel structure of insert and search suggests that we're missing a condition for (i == n->data)
in the insert; in that block, we should avoid inserting a duplicate node and instead return early:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i == node->data) {
return; /* already exists */
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
(It might be this change that eliminated the Valgrind warning about uninitialised data - I'm not sure when that disappeared).
We're missing the check that malloc()
didn't return a null pointer. That can happen any time we call an allocation function, so we must always test the result before using it. In particular, there's no guarantee that the subsequent use of a null pointer will crash the program, as some authors seem to think.
bool BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
if (!node) return false;
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
return true;
} else if (i == node->data) {
return true; /* already exists */
} else if (i > node->data) {
return BSTInsert(i, &node->BSTRight);
} else {
return BSTInsert(i, &node->BSTLeft);
}
}
Don't forget that this means that the callers of BSTInsert
now need to check that it succeeded!
Lastly (and leastly), this comment is inaccurate:
// Main function for these three scenarios.
Either change the word "three" to "two" or remove the comment (it's stating the obvious, so doesn't add any value).
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
You need to adjust that call to pass the value ofrootNode
rather than a pointer to it:BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!
– Toby Speight
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
add a comment |
up vote
1
down vote
Do not cast results of
malloc
.BSTSearch
does not modify the tree, so there is no need to use double indirection.BSTSearch(int i, node *n)
works well.BSTSearch
does the search, but does not tell the caller whether the search was successful or not. Return something useful (a matching node e.g.).I do not endorse recursion when an iterative solution is readily available.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
The global variable rootNode
is never used, and is confusing due to similar local variables, so remove it.
As we're ignoring all command-line arguments, we can use the simpler signature for main()
:
int main(void)
Prefer to use unsigned types for counting:
const unsigned int SIZE = 10000;
...
for (unsigned int i = 1; i < SIZE; ++i)
That addresses most of the compiler warnings I get for this code. The remaining warning is best eliminated with a cast to indicate that we don't care about preserving the correct value in this signed → unsigned conversion:
srand((unsigned)time(NULL));
Prefer to use the size of the variable than of its type when allocating memory. This makes it easier for reviewers to confirm that the sizes match:
if (!*n) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
and
int *a = malloc(sizeof *a * SIZE);
Use a memory checker; at the moment, we leak the entire BST:
Inserting values to BST with 10000 random nodes...
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x1091FC: BSTInsert (209085.c:24)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Done. Took 3.30890200 seconds
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10926D: BSTSearch (209085.c:33)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10927B: BSTSearch (209085.c:35)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Searching random values in BST...
Done. Took 0.00558500 seconds
Inserting values to BST with 10000 sorted nodes...
Done. Took 3.36596000 seconds
Searching sorted values in BST...
Done. Took 3.96642300 seconds
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x1094AA: test_scenario2 (209085.c:79)
==12434== by 0x109579: main (209085.c:97)
==12434==
Those early reports of using uninitialised values are certainly worth investigating, too.
Try to be consistent where that helps readers. Consider this fragment:
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
See how it's easier to see the relation between the two tests if we write the operands in the same order:
else if (i == (*n)->data)
return;
else if (i > (*n)->data)
Use the standard error stream for error messages:
if (*n == NULL)
fprintf(stderr, "Value does not exist in tree!n");
And prefer to write complete lines to output (especially relevant when it's connected to line-buffered devices, such as terminals and terminal-emulators).
Consider using more braces to enclose conditional commands. It's easier to avoid silly mistakes:
if (*n == NULL) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
} else if (i > (*n)->data) {
BSTInsert(i, &((*n)->BSTRight));
} else {
BSTInsert(i, &((*n)->BSTLeft));
}
We could make that code a lot clearer by copying *n
into a local variable:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
On the other hand, in the search function, we don't need to pass by pointer, and we can use const
. We probably ought to return something, too:
const int *BSTSearch(int i, const node *n) {
if (n == NULL) {
fprintf(stderr, "Value does not exist in tree!n");
return NULL;
} else if (i == n->data) {
return &n->data;
} else if (i > n->data) {
return BSTSearch(i, n->BSTRight);
} else {
return BSTSearch(i, n->BSTLeft);
}
}
Obviously, the call sites would then need to pass rootNode
by value, rather than &rootNode
pointer.
The parallel structure of insert and search suggests that we're missing a condition for (i == n->data)
in the insert; in that block, we should avoid inserting a duplicate node and instead return early:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i == node->data) {
return; /* already exists */
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
(It might be this change that eliminated the Valgrind warning about uninitialised data - I'm not sure when that disappeared).
We're missing the check that malloc()
didn't return a null pointer. That can happen any time we call an allocation function, so we must always test the result before using it. In particular, there's no guarantee that the subsequent use of a null pointer will crash the program, as some authors seem to think.
bool BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
if (!node) return false;
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
return true;
} else if (i == node->data) {
return true; /* already exists */
} else if (i > node->data) {
return BSTInsert(i, &node->BSTRight);
} else {
return BSTInsert(i, &node->BSTLeft);
}
}
Don't forget that this means that the callers of BSTInsert
now need to check that it succeeded!
Lastly (and leastly), this comment is inaccurate:
// Main function for these three scenarios.
Either change the word "three" to "two" or remove the comment (it's stating the obvious, so doesn't add any value).
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
You need to adjust that call to pass the value ofrootNode
rather than a pointer to it:BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!
– Toby Speight
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
add a comment |
up vote
2
down vote
accepted
The global variable rootNode
is never used, and is confusing due to similar local variables, so remove it.
As we're ignoring all command-line arguments, we can use the simpler signature for main()
:
int main(void)
Prefer to use unsigned types for counting:
const unsigned int SIZE = 10000;
...
for (unsigned int i = 1; i < SIZE; ++i)
That addresses most of the compiler warnings I get for this code. The remaining warning is best eliminated with a cast to indicate that we don't care about preserving the correct value in this signed → unsigned conversion:
srand((unsigned)time(NULL));
Prefer to use the size of the variable than of its type when allocating memory. This makes it easier for reviewers to confirm that the sizes match:
if (!*n) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
and
int *a = malloc(sizeof *a * SIZE);
Use a memory checker; at the moment, we leak the entire BST:
Inserting values to BST with 10000 random nodes...
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x1091FC: BSTInsert (209085.c:24)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Done. Took 3.30890200 seconds
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10926D: BSTSearch (209085.c:33)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10927B: BSTSearch (209085.c:35)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Searching random values in BST...
Done. Took 0.00558500 seconds
Inserting values to BST with 10000 sorted nodes...
Done. Took 3.36596000 seconds
Searching sorted values in BST...
Done. Took 3.96642300 seconds
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x1094AA: test_scenario2 (209085.c:79)
==12434== by 0x109579: main (209085.c:97)
==12434==
Those early reports of using uninitialised values are certainly worth investigating, too.
Try to be consistent where that helps readers. Consider this fragment:
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
See how it's easier to see the relation between the two tests if we write the operands in the same order:
else if (i == (*n)->data)
return;
else if (i > (*n)->data)
Use the standard error stream for error messages:
if (*n == NULL)
fprintf(stderr, "Value does not exist in tree!n");
And prefer to write complete lines to output (especially relevant when it's connected to line-buffered devices, such as terminals and terminal-emulators).
Consider using more braces to enclose conditional commands. It's easier to avoid silly mistakes:
if (*n == NULL) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
} else if (i > (*n)->data) {
BSTInsert(i, &((*n)->BSTRight));
} else {
BSTInsert(i, &((*n)->BSTLeft));
}
We could make that code a lot clearer by copying *n
into a local variable:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
On the other hand, in the search function, we don't need to pass by pointer, and we can use const
. We probably ought to return something, too:
const int *BSTSearch(int i, const node *n) {
if (n == NULL) {
fprintf(stderr, "Value does not exist in tree!n");
return NULL;
} else if (i == n->data) {
return &n->data;
} else if (i > n->data) {
return BSTSearch(i, n->BSTRight);
} else {
return BSTSearch(i, n->BSTLeft);
}
}
Obviously, the call sites would then need to pass rootNode
by value, rather than &rootNode
pointer.
The parallel structure of insert and search suggests that we're missing a condition for (i == n->data)
in the insert; in that block, we should avoid inserting a duplicate node and instead return early:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i == node->data) {
return; /* already exists */
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
(It might be this change that eliminated the Valgrind warning about uninitialised data - I'm not sure when that disappeared).
We're missing the check that malloc()
didn't return a null pointer. That can happen any time we call an allocation function, so we must always test the result before using it. In particular, there's no guarantee that the subsequent use of a null pointer will crash the program, as some authors seem to think.
bool BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
if (!node) return false;
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
return true;
} else if (i == node->data) {
return true; /* already exists */
} else if (i > node->data) {
return BSTInsert(i, &node->BSTRight);
} else {
return BSTInsert(i, &node->BSTLeft);
}
}
Don't forget that this means that the callers of BSTInsert
now need to check that it succeeded!
Lastly (and leastly), this comment is inaccurate:
// Main function for these three scenarios.
Either change the word "three" to "two" or remove the comment (it's stating the obvious, so doesn't add any value).
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
You need to adjust that call to pass the value ofrootNode
rather than a pointer to it:BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!
– Toby Speight
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
The global variable rootNode
is never used, and is confusing due to similar local variables, so remove it.
As we're ignoring all command-line arguments, we can use the simpler signature for main()
:
int main(void)
Prefer to use unsigned types for counting:
const unsigned int SIZE = 10000;
...
for (unsigned int i = 1; i < SIZE; ++i)
That addresses most of the compiler warnings I get for this code. The remaining warning is best eliminated with a cast to indicate that we don't care about preserving the correct value in this signed → unsigned conversion:
srand((unsigned)time(NULL));
Prefer to use the size of the variable than of its type when allocating memory. This makes it easier for reviewers to confirm that the sizes match:
if (!*n) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
and
int *a = malloc(sizeof *a * SIZE);
Use a memory checker; at the moment, we leak the entire BST:
Inserting values to BST with 10000 random nodes...
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x1091FC: BSTInsert (209085.c:24)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Done. Took 3.30890200 seconds
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10926D: BSTSearch (209085.c:33)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10927B: BSTSearch (209085.c:35)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Searching random values in BST...
Done. Took 0.00558500 seconds
Inserting values to BST with 10000 sorted nodes...
Done. Took 3.36596000 seconds
Searching sorted values in BST...
Done. Took 3.96642300 seconds
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x1094AA: test_scenario2 (209085.c:79)
==12434== by 0x109579: main (209085.c:97)
==12434==
Those early reports of using uninitialised values are certainly worth investigating, too.
Try to be consistent where that helps readers. Consider this fragment:
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
See how it's easier to see the relation between the two tests if we write the operands in the same order:
else if (i == (*n)->data)
return;
else if (i > (*n)->data)
Use the standard error stream for error messages:
if (*n == NULL)
fprintf(stderr, "Value does not exist in tree!n");
And prefer to write complete lines to output (especially relevant when it's connected to line-buffered devices, such as terminals and terminal-emulators).
Consider using more braces to enclose conditional commands. It's easier to avoid silly mistakes:
if (*n == NULL) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
} else if (i > (*n)->data) {
BSTInsert(i, &((*n)->BSTRight));
} else {
BSTInsert(i, &((*n)->BSTLeft));
}
We could make that code a lot clearer by copying *n
into a local variable:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
On the other hand, in the search function, we don't need to pass by pointer, and we can use const
. We probably ought to return something, too:
const int *BSTSearch(int i, const node *n) {
if (n == NULL) {
fprintf(stderr, "Value does not exist in tree!n");
return NULL;
} else if (i == n->data) {
return &n->data;
} else if (i > n->data) {
return BSTSearch(i, n->BSTRight);
} else {
return BSTSearch(i, n->BSTLeft);
}
}
Obviously, the call sites would then need to pass rootNode
by value, rather than &rootNode
pointer.
The parallel structure of insert and search suggests that we're missing a condition for (i == n->data)
in the insert; in that block, we should avoid inserting a duplicate node and instead return early:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i == node->data) {
return; /* already exists */
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
(It might be this change that eliminated the Valgrind warning about uninitialised data - I'm not sure when that disappeared).
We're missing the check that malloc()
didn't return a null pointer. That can happen any time we call an allocation function, so we must always test the result before using it. In particular, there's no guarantee that the subsequent use of a null pointer will crash the program, as some authors seem to think.
bool BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
if (!node) return false;
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
return true;
} else if (i == node->data) {
return true; /* already exists */
} else if (i > node->data) {
return BSTInsert(i, &node->BSTRight);
} else {
return BSTInsert(i, &node->BSTLeft);
}
}
Don't forget that this means that the callers of BSTInsert
now need to check that it succeeded!
Lastly (and leastly), this comment is inaccurate:
// Main function for these three scenarios.
Either change the word "three" to "two" or remove the comment (it's stating the obvious, so doesn't add any value).
The global variable rootNode
is never used, and is confusing due to similar local variables, so remove it.
As we're ignoring all command-line arguments, we can use the simpler signature for main()
:
int main(void)
Prefer to use unsigned types for counting:
const unsigned int SIZE = 10000;
...
for (unsigned int i = 1; i < SIZE; ++i)
That addresses most of the compiler warnings I get for this code. The remaining warning is best eliminated with a cast to indicate that we don't care about preserving the correct value in this signed → unsigned conversion:
srand((unsigned)time(NULL));
Prefer to use the size of the variable than of its type when allocating memory. This makes it easier for reviewers to confirm that the sizes match:
if (!*n) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
}
and
int *a = malloc(sizeof *a * SIZE);
Use a memory checker; at the moment, we leak the entire BST:
Inserting values to BST with 10000 random nodes...
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x1091FC: BSTInsert (209085.c:24)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Done. Took 3.30890200 seconds
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10926D: BSTSearch (209085.c:33)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== Conditional jump or move depends on uninitialised value(s)
==12434== at 0x10927B: BSTSearch (209085.c:35)
==12434== by 0x10940C: test_scenario1 (209085.c:64)
==12434== by 0x10956F: main (209085.c:96)
==12434==
Searching random values in BST...
Done. Took 0.00558500 seconds
Inserting values to BST with 10000 sorted nodes...
Done. Took 3.36596000 seconds
Searching sorted values in BST...
Done. Took 3.96642300 seconds
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x109388: test_scenario1 (209085.c:54)
==12434== by 0x10956F: main (209085.c:96)
==12434==
==12434== 240,000 (24 direct, 239,976 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 23
==12434== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12434== by 0x1091B9: BSTInsert (209085.c:19)
==12434== by 0x1094AA: test_scenario2 (209085.c:79)
==12434== by 0x109579: main (209085.c:97)
==12434==
Those early reports of using uninitialised values are certainly worth investigating, too.
Try to be consistent where that helps readers. Consider this fragment:
else if((*n)->data == i)
return ;
else if(i > (*n)->data)
See how it's easier to see the relation between the two tests if we write the operands in the same order:
else if (i == (*n)->data)
return;
else if (i > (*n)->data)
Use the standard error stream for error messages:
if (*n == NULL)
fprintf(stderr, "Value does not exist in tree!n");
And prefer to write complete lines to output (especially relevant when it's connected to line-buffered devices, such as terminals and terminal-emulators).
Consider using more braces to enclose conditional commands. It's easier to avoid silly mistakes:
if (*n == NULL) {
*n = malloc(sizeof **n);
(*n)->BSTLeft = NULL;
(*n)->BSTRight = NULL;
(*n)->data = i;
} else if (i > (*n)->data) {
BSTInsert(i, &((*n)->BSTRight));
} else {
BSTInsert(i, &((*n)->BSTLeft));
}
We could make that code a lot clearer by copying *n
into a local variable:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
On the other hand, in the search function, we don't need to pass by pointer, and we can use const
. We probably ought to return something, too:
const int *BSTSearch(int i, const node *n) {
if (n == NULL) {
fprintf(stderr, "Value does not exist in tree!n");
return NULL;
} else if (i == n->data) {
return &n->data;
} else if (i > n->data) {
return BSTSearch(i, n->BSTRight);
} else {
return BSTSearch(i, n->BSTLeft);
}
}
Obviously, the call sites would then need to pass rootNode
by value, rather than &rootNode
pointer.
The parallel structure of insert and search suggests that we're missing a condition for (i == n->data)
in the insert; in that block, we should avoid inserting a duplicate node and instead return early:
void BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
} else if (i == node->data) {
return; /* already exists */
} else if (i > node->data) {
BSTInsert(i, &node->BSTRight);
} else {
BSTInsert(i, &node->BSTLeft);
}
}
(It might be this change that eliminated the Valgrind warning about uninitialised data - I'm not sure when that disappeared).
We're missing the check that malloc()
didn't return a null pointer. That can happen any time we call an allocation function, so we must always test the result before using it. In particular, there's no guarantee that the subsequent use of a null pointer will crash the program, as some authors seem to think.
bool BSTInsert(int i, node **n)
{
node *node = *n;
if (!node) {
*n = node = malloc(sizeof **n);
if (!node) return false;
node->BSTLeft = NULL;
node->BSTRight = NULL;
node->data = i;
return true;
} else if (i == node->data) {
return true; /* already exists */
} else if (i > node->data) {
return BSTInsert(i, &node->BSTRight);
} else {
return BSTInsert(i, &node->BSTLeft);
}
}
Don't forget that this means that the callers of BSTInsert
now need to check that it succeeded!
Lastly (and leastly), this comment is inaccurate:
// Main function for these three scenarios.
Either change the word "three" to "two" or remove the comment (it's stating the obvious, so doesn't add any value).
edited yesterday
answered yesterday
Toby Speight
23.2k538110
23.2k538110
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
You need to adjust that call to pass the value ofrootNode
rather than a pointer to it:BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!
– Toby Speight
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
add a comment |
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
You need to adjust that call to pass the value ofrootNode
rather than a pointer to it:BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!
– Toby Speight
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
OMG. i am almost missing every thing. that really was a very helpful review. any idea of using a memory checker?. in the main function, am i right what i am talking about? i mean do these functions insert and search values to BST randomly and sorted values? is that really working, or do i miss something? Actually i had three scenarios for testing, but later decided to have two, the comment is still there and i will just remove it.
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.
main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
When i am trying to apply this part on your review: "On the other hand, in the search function, we don't need to pass by pointer, and we can use const. We probably ought to return something, too" then i am getting this error.
main.c: In function ‘test_scenario1’: main.c:70:21: warning: passing argument 2 of ‘BSTSearch’ from incompatible pointer type [-Wincompatible-pointer-types] BSTSearch(a[i], &rootNode);
– Hefaz
yesterday
You need to adjust that call to pass the value of
rootNode
rather than a pointer to it: BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!– Toby Speight
yesterday
You need to adjust that call to pass the value of
rootNode
rather than a pointer to it: BSTSearch(a[i], rootNode);
. I apologise for assuming that it was obvious to you!– Toby Speight
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
Got it. i really appreciate your review. thanks for your time.
– Hefaz
yesterday
add a comment |
up vote
1
down vote
Do not cast results of
malloc
.BSTSearch
does not modify the tree, so there is no need to use double indirection.BSTSearch(int i, node *n)
works well.BSTSearch
does the search, but does not tell the caller whether the search was successful or not. Return something useful (a matching node e.g.).I do not endorse recursion when an iterative solution is readily available.
add a comment |
up vote
1
down vote
Do not cast results of
malloc
.BSTSearch
does not modify the tree, so there is no need to use double indirection.BSTSearch(int i, node *n)
works well.BSTSearch
does the search, but does not tell the caller whether the search was successful or not. Return something useful (a matching node e.g.).I do not endorse recursion when an iterative solution is readily available.
add a comment |
up vote
1
down vote
up vote
1
down vote
Do not cast results of
malloc
.BSTSearch
does not modify the tree, so there is no need to use double indirection.BSTSearch(int i, node *n)
works well.BSTSearch
does the search, but does not tell the caller whether the search was successful or not. Return something useful (a matching node e.g.).I do not endorse recursion when an iterative solution is readily available.
Do not cast results of
malloc
.BSTSearch
does not modify the tree, so there is no need to use double indirection.BSTSearch(int i, node *n)
works well.BSTSearch
does the search, but does not tell the caller whether the search was successful or not. Return something useful (a matching node e.g.).I do not endorse recursion when an iterative solution is readily available.
edited yesterday
Toby Speight
23.2k538110
23.2k538110
answered yesterday
vnp
38.2k13096
38.2k13096
add a comment |
add a comment |
Hefaz is a new contributor. Be nice, and check out our Code of Conduct.
Hefaz is a new contributor. Be nice, and check out our Code of Conduct.
Hefaz is a new contributor. Be nice, and check out our Code of Conduct.
Hefaz is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209085%2funbalanced-binary-search-tree-insertion-and-search-with-random-and-sorted-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday