I am student and I am beginner at C.
I want to make binary search tree by using command line.
I want to enter the number composing BTS by using command line.
I have to make it by using pointer and print it by using preorder.
I delete some code because it's too much code in this question.(delete part)
how to make it?
I can't know how to make main part.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data; //정수를 보관할 노드
struct node *left_child; // 왼쪽 자식
struct node *right_child; // 오른쪽 자식
};
struct node* search(struct node *root, int x)
{
if (root=NULL || root->data==x) // root가 없거나 data가 root와 같다면 root를 리턴
return root;
else if (x > root->data)
return search(root->right_child, x);
else
return search(root->left_child, x);
}
struct node* find_minimum(struct node *root)
{
if(root==NULL)
return NULL;
else if(root->left_child != NULL)
return find_minimum(root->left_child);
return root;
}
struct node* new_node(int x)
{
struct node *p;
p = malloc(sizeof(struct node));
p->data = x;
p->left_child = NULL;
p->right_child = NULL;
return p;
}
struct node* insert(struct node *root, int x)
{
if(root==NULL)
return new_node(x);
else if(x<root->data)
root->left_child = insert(root->left_child,x);
else
root->right_child = insert(root->right_child, x);
return root;
}
void preorder(struct node *root)
{
if(root!=NULL)
{
printf("%d", root->data);
preorder(root->left_child);
preorder(root->right_child);
}
}
int main()
{
struct node *root;
int number;
int num_count = 0;
while(1)
{
scanf("%d", &number);
printf("%d", &number);
if (num_count = 0)
{
root = new_node(number);
num_count += 1;
}
else
if(number == EOF)
{
break;
}
else
{
insert(root, number);
}
}
preorder(root);
return 0;
}
There are multiple problems in your code:
The test if (root=NULL || root->data==x) is incorrect: = is the assignment operator, very different from the comparison operator ==. Use if (root == NULL || root->data == x)
&number is the address of variable number. Passing the address is required for scanf() to store the converted value into the destination object, but you should just pass the value to printf, without the & operator.
scanf() returns the number of successful conversions. Testing if (number == EOF) is surprising, you should test if (scanf("%d", &number) != 1) and possibly if (number < 0) if entering a negative number means end of input.
printf("%d", root->data); outputs just the digits, without any extra space or newline, causing all output to appear as a single string of digits. Add spaces and newlines to make the output more readable.
there is no need to special case the first node: initializing root as NULL and using root = insert(root, number); for each node is safer as it allows for an empty tree.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data; //정수를 보관할 노드
struct node *left_child; // 왼쪽 자식
struct node *right_child; // 오른쪽 자식
};
struct node *search(struct node *root, int x) {
if (root == NULL || root->data == x) // root가 없거나 data가 root와 같다면 root를 리턴
return root;
else
if (x > root->data)
return search(root->right_child, x);
else
return search(root->left_child, x);
}
struct node *find_minimum(struct node *root) {
if (root != NULL && root->left_child != NULL)
return find_minimum(root->left_child);
else
return root;
}
struct node *new_node(int x) {
struct node *p = malloc(sizeof(struct node));
if (p != NULL) {
p->data = x;
p->left_child = NULL;
p->right_child = NULL;
}
return p;
}
struct node *insert(struct node *root, int x) {
if (root == NULL)
return new_node(x);
else if (x < root->data)
root->left_child = insert(root->left_child, x);
else
root->right_child = insert(root->right_child, x);
return root;
}
void preorder(struct node *root) {
if (root != NULL) {
printf("%d ", root->data);
preorder(root->left_child);
preorder(root->right_child);
}
}
void free_tree(struct node *root) {
if (root != NULL) {
free_tree(root->left_child);
free_tree(root->right_child);
free(root);
}
}
int main() {
struct node *root = NULL;
int number;
while (scanf("%d", &number) == 1 && number >= 0) {
printf("%d\n", number);
root = insert(root, number);
}
preorder(root);
printf("\n");
free_tree(root);
return 0;
}
Related
I have based this code on the Wikipedia article about red-black trees and on the part about red-black trees in the CLRS book "Introduction to Algorithms". This program displays the expected results if I run it. Now I would like to verify that it is good. How can one verify the properties and not just simply test it for certain cases? I would like to verify that the code fulfills the specification. I suppose that I could write a test case building up a large red-black tree and then deallocating it but that is still only a test and not a complete verification.
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
static char BLACK = 'b';
static char RED = 'r';
struct node {
int key;
char color;
struct node *left, *right, *parent;
};
void insert_repair_tree(struct node* n);
void delete_case1(struct node* n);
void delete_case2(struct node* n);
void delete_case3(struct node* n);
void delete_case4(struct node* n);
void delete_case5(struct node* n);
struct node *LEAF;
struct node *parent(struct node *n) {
return n->parent; // NULL for root node
}
struct node *grandparent(struct node *n) {
struct node *p = parent(n);
if (p == NULL)
return NULL; // No parent means no grandparent
return parent(p); // NULL if parent is root
}
struct node *sibling(struct node *n) {
struct node *p = parent(n);
if (p == NULL)
return NULL; // No parent means no sibling
if (n == p->left)
return p->right;
else
return p->left;
}
struct node *uncle(struct node *n) {
struct node *p = parent(n);
struct node *g = grandparent(n);
if (g == NULL)
return NULL; // No grandparent means no uncle
return sibling(p);
}
void rotate_left(struct node *n) {
struct node *nnew = n->right;
struct node *p = parent(n);
assert(nnew != NULL); // since the leaves of a red-black tree are empty, they cannot become internal nodes
n->right = nnew->left;
nnew->left = n;
n->parent = nnew;
// handle other child/parent pointers
if (n->right != NULL)
n->right->parent = n;
if (p != NULL) // initially n could be the root
{
if (n == p->left)
p->left = nnew;
else if (n == p->right) // if (...) is excessive
p->right = nnew;
}
nnew->parent = p;
}
void rotate_right(struct node *n) {
struct node *nnew = n->left;
struct node *p = parent(n);
assert(nnew != NULL); // since the leaves of a red-black tree are empty, they cannot become internal nodes
n->left = nnew->right;
nnew->right = n;
n->parent = nnew;
// handle other child/parent pointers
if (n->left != NULL)
n->left->parent = n;
if (p != NULL) // initially n could be the root
{
if (n == p->left)
p->left = nnew;
else if (n == p->right) // if (...) is excessive
p->right = nnew;
}
nnew->parent = p;
}
void insert_recurse(struct node* root, struct node* n) {
// recursively descend the tree until a leaf is found
if (root != NULL && n->key < root->key) {
if (root->left != LEAF) {
insert_recurse(root->left, n);
return;
}
else
root->left = n;
} else if (root != NULL) {
if (root->right != LEAF){
insert_recurse(root->right, n);
return;
}
else
root->right = n;
}
// insert new node n
n->parent = root;
n->left = LEAF;
n->right = LEAF;
n->color = RED;
}
void insert_case1(struct node* n)
{
if (parent(n) == NULL)
n->color = BLACK;
}
void insert_case2(struct node* n)
{
return; /* Do nothing since tree is still valid */
}
void insert_case3(struct node* n)
{
parent(n)->color = BLACK;
uncle(n)->color = BLACK;
grandparent(n)->color = RED;
insert_repair_tree(grandparent(n));
}
void insert_case4step2(struct node* n)
{
struct node* p = parent(n);
struct node* g = grandparent(n);
if (n == p->left)
rotate_right(g);
else
rotate_left(g);
p->color = BLACK;
g->color = RED;
}
void insert_case4(struct node* n)
{
struct node* p = parent(n);
struct node* g = grandparent(n);
if (n == g->left->right) {
rotate_left(p);
n = n->left;
} else if (n == g->right->left) {
rotate_right(p);
n = n->right;
}
insert_case4step2(n);
}
void insert_repair_tree(struct node* n) {
if (parent(n) == NULL) {
insert_case1(n);
} else if (parent(n)->color == BLACK) {
insert_case2(n);
} else if (uncle(n)->color == RED) {
insert_case3(n);
} else {
insert_case4(n);
}
}
struct node *insert(struct node* root, struct node* n) {
// insert new node into the current tree
insert_recurse(root, n);
// repair the tree in case any of the red-black properties have been violated
insert_repair_tree(n);
// find the new root to return
root = n;
while (parent(root) != NULL)
root = parent(root);
return root;
}
void replace_node(struct node* n, struct node* child){
child->parent = n->parent;
if (n == n->parent->left)
n->parent->left = child;
else
n->parent->right = child;
}
int is_leaf(struct node* n){
if(n->right ==NULL && n->left == NULL)
return 1;
else return 0;
}
void delete_one_child(struct node* n)
{
/*
* Precondition: n has at most one non-leaf child.
*/
struct node* child = is_leaf(n->right) ? n->left : n->right;
replace_node(n, child);
if (n->color == BLACK) {
if (child->color == RED)
child->color = BLACK;
else
delete_case1(child);
}
free(n);
}
void delete_case1(struct node* n)
{
if (n->parent != NULL)
delete_case2(n);
}
void delete_case2(struct node* n)
{
struct node* s = sibling(n);
if (s->color == RED) {
n->parent->color = RED;
s->color = BLACK;
if (n == n->parent->left)
rotate_left(n->parent);
else
rotate_right(n->parent);
}
delete_case3(n);
}
void delete_case3(struct node* n)
{
struct node* s = sibling(n);
if ((n->parent->color == BLACK) &&
(s->color == BLACK) &&
(s->left->color == BLACK) &&
(s->right->color == BLACK)) {
s->color = RED;
delete_case1(n->parent);
} else
delete_case4(n);
}
void delete_case4(struct node* n)
{
struct node* s = sibling(n);
if ((n->parent->color == RED) &&
(s->color == BLACK) &&
(s->left->color == BLACK) &&
(s->right->color == BLACK)) {
s->color = RED;
n->parent->color = BLACK;
} else
delete_case5(n);
}
void delete_case6(struct node* n)
{
struct node* s = sibling(n);
s->color = n->parent->color;
n->parent->color = BLACK;
if (n == n->parent->left) {
s->right->color = BLACK;
rotate_left(n->parent);
} else {
s->left->color = BLACK;
rotate_right(n->parent);
}
}
void delete_case5(struct node* n)
{
struct node* s = sibling(n);
if (s->color == BLACK) { /* this if statement is trivial,
due to case 2 (even though case 2 changed the sibling to a sibling's child,
the sibling's child can't be red, since no red parent can have a red child). */
/* the following statements just force the red to be on the left of the left of the parent,
or right of the right, so case six will rotate correctly. */
if ((n == n->parent->left) &&
(s->right->color == BLACK) &&
(s->left->color == RED)) { /* this last test is trivial too due to cases 2-4. */
s->color = RED;
s->left->color = BLACK;
rotate_right(s);
} else if ((n == n->parent->right) &&
(s->left->color == BLACK) &&
(s->right->color == RED)) {/* this last test is trivial too due to cases 2-4. */
s->color = RED;
s->right->color = BLACK;
rotate_left(s);
}
}
delete_case6(n);
}
struct node* search(struct node *temp, int val) {
int diff;
while (!is_leaf(temp)) {
diff = val - temp->key;
if (diff > 0) {
temp = temp->right;
} else if (diff < 0) {
temp = temp->left;
} else {
printf("Search Element Found!!\n");
return temp;
}
}
printf("Given Data Not Found in the tree!!\n");
return 0;
}
void inorderTree(struct node *root) {
struct node *temp = root;
if (temp != NULL) {
inorderTree(temp->left);
printf(" %d--%c ", temp->key, temp->color);
inorderTree(temp->right);
}
}
void postorderTree(struct node *root) {
struct node *temp = root;
if (temp != NULL) {
postorderTree(temp->left);
postorderTree(temp->right);
printf(" %d--%c ", temp->key, temp->color);
}
}
void traversal(struct node *root) {
if (root != NULL) {
printf("root is %d-- %c", root->key, root->color);
printf("\nInorder tree traversal\n");
inorderTree(root);
printf("\npostorder tree traversal\n");
postorderTree(root);
}
}
int main() {
printf("Hello!\n");
struct node *root = NULL;//malloc(sizeof(struct node));
LEAF = malloc(sizeof(struct node));
LEAF->color=BLACK;
LEAF->left=NULL;
LEAF->right=NULL;
LEAF->key=0;
int choice, val, var, fl = 0;
while (1) {
setbuf(stdout, 0); // Bugfix for debugging mode on Windows
printf("\nEnter your choice :1:Add 2:Delete 3:Find 4:Traverse 5: Test 6:Exit\n");
scanf("%d", &choice);
switch (choice) {
case 1:
setbuf(stdout, 0);
printf("Enter the integer you want to add : ");
scanf("%d", &val);
struct node *z = malloc(sizeof(struct node));
z->key = val;
z->left = NULL;
z->right = NULL;
z->parent = NULL;
z->color = RED;
root = insert(root, z);
printf("The root is now %d: ", root->key);
break;
case 2:
printf("Enter the integer you want to delete : ");
scanf("%d", &var);
delete_one_child(search(root, var));
break;
case 3:
printf("Enter search element \n");
scanf("%d", &val);
search(root, val);
break;
case 4:
traversal(root);
break;
case 5: // TODO
//test();
break;
case 6:
fl = 1;
break;
default:
printf("\nInvalid Choice\n");
}
if (fl == 1) { break; }
}
return 0;
}
There is verification, and there is proof. Perhaps by "complete verification" you mean formal proof of code correctness. However, in many places verification means:
functions that test properties of the data structure
applied repeatedly after several rounds of insertions and/or deletions
combined with code coverage metrics ensuring that all of your code is exercised
With map-like data structures I like to keep a simple parallel data structure, such as a hashtable of all keys in the tree. Then among the tests executed after each round of insertions and/or deletions, you can verify that all the expected keys are in the tree, as well as that the tree has correct size. Of course, this is in addition to the basic tests that the red-black invariant holds, and that the tree is sufficiently balanced, and that the tree is ordered.
It's wise to use a random key generator, with parameters for the range of key sizes, to avoid biasing your tests. Add a random selection of insert, lookup, or delete operations, with a ratio dynamically biased to grow the tree to a sufficiently large size. Run it for a few hours and see if you can get 100% code coverage; extra credit for MC/DC coverage.
A theoretical examination of the implementation is discussed in the Wikipedia article you reference.
If you want to test your particular implementation, then write the tests for each feature you want to test. Using the Wikipedia case studies would be a good start.
There are full formal proofs of red-black trees available online but it would be up to you to generate a formal proof of your particular implementation. Most people feel that formal proofs of programming programs are not worthwhile or useful.
I am trying to see if tree A is the preorder traversal of tree B and to do so, I created two trees which during a transversal were supposed to save the values. However, after hours of debugging I found out that the trees values were ALWAYS 0. I am confused as to why the trees values are 0. I've done a multitude of print statements (some of which I've left in the code posted below) and I just cannot seem to pinpoint why this is happening. Can someone please nudge me in the correct direction? I thought maybe the function was deleting variables as it exited and in effort to get to the bottom of the issue I had the preorder function return the tree ( as seen below), however, the output is ALWAYS 0 for the tree.
Code:
typedef struct node
{
// Each node holds a single integer.
int data;
// Pointers to the node's left and right children.
struct node *left, *right;
} node;
int tree_diff(node *a, node *b)
{
if (a == NULL && b == NULL)
return 0;
else if (a == NULL || b == NULL)
return 1;
else if (a->data != b->data)
return 1;
printf("A %d , B %d", a->data, b->data);
return tree_diff(a->left, b->left) || tree_diff(a->right, b->right);
}
node *preorder_recursive(node *root, node *A)
{
if (root == NULL)
return A;
printf("root %d ", root->data);
A = root;
printf("= data %d\n", A->data);
preorder_recursive(root->left, A->left);
preorder_recursive(root->right, A->right);
}
void postorder_recursive(node *root, node *B)
{
if (root == NULL)
return;
B = root;
postorder_recursive(root->left, B->left);
postorder_recursive(root->right, B->right);
printf("root %d ", root->data);
printf("= data %d\n", B->data);
}
int kindredSpirits(node *a, node *b)
{
// Get the preorder of a
node *A = malloc(sizeof(node));
A = preorder_recursive(a, A);
// Get the postorder of b
printf("\n\n");
node *B = malloc(sizeof(node));
postorder_recursive(b, B);
if(tree_diff(A,B) == 1)
return 0;
else
return 1;
}
The test case:
#include <stdio.h>
#include <stdlib.h>
#include "KindredSpirits.h"
node *create_node(int data)
{
node *n = malloc(sizeof(node));
n->data = data;
n->left = n->right = NULL;
return n;
}
node *forest_fire(node *root)
{
if (root == NULL)
return NULL;
forest_fire(root->left);
forest_fire(root->right);
free(root);
}
int main(void)
{
node *root;
root = create_node(23);
root->left = create_node(12);
root->left->left = create_node(5);
root->left->right = create_node(18);
root->right = create_node(71);
root->right->right = create_node(56);
printf("%s\n", !kindredSpirits(root, root) ? "Success!" : "fail whale :(");
forest_fire(root);
return 0;
}
Here's a code fragment that should get you started:
typedef struct node {
// Each node holds a single integer.
int data;
// Pointers to the node's left and right children.
struct node *left,
struct node *right;
} node;
typedef struct list {
int lst_max; // maximum number of allocated cells
int lst_cur; // current number of filled cells
int *lst_base; // traversal list
} list;
list list_a = { 0, 0, NULL };
list list_b = { 0, 0, NULL };
void
list_append(list *lst,int data)
{
int newidx;
newidx = lst->lst_cur;
if (newidx >= lst->lst_max) {
lst->lst_max += 100;
lst->lst_base = realloc(lst->lst_base,sizeof(int) * lst->lst_max);
if (lst->lst_base == NULL) {
printf("list_append: malloc error\n");
exit(1);
}
}
lst->lst_base[newidx] = data;
lst->lst_cur = newidx + 1;
}
void
preorder_recursive(node *root,list *lst)
{
if (root == NULL)
return;
list_append(lst,root->data);
preorder_recursive(root->left,lst);
preorder_recursive(root->right,lst);
}
void
postorder_recursive(node *root,list *lst)
{
if (root == NULL)
return;
postorder_recursive(root->left,lst);
postorder_recursive(root->right,lst);
list_append(lst,root->data);
}
int
main(void)
{
preorder_recursive(a,&list_a);
postorder_recursive(b,&list_b);
// compare list_a and list_b ...
return 0;
}
I'm trying to write a function that figures out if tree a's preorder is equal to tree b's postorder without altering a or b.
I use arrays to save the traversals and then compare the value of the two arrays.
#define MAX_TREE_SIZE 100
void preorder_recursive(node *root, int* arr, int *len) {
if (root != NULL){
arr[(*len)++] = root->data;
preorder_recursive(root->left, arr, len);
preorder_recursive(root->right, arr, len);
}
}
void postorder_recursive(node *root, int *arr, int *len) {
if (root != NULL){
postorder_recursive(root->left, arr, len);
postorder_recursive(root->right, arr, len);
arr[(*len)++] = root->data;
}
}
int kindredSpirits(node *a, node *b){
// Get the preorder of a
int *arr1 = malloc(MAX_TREE_SIZE * sizeof(int));
int len1 = 0;
preorder_recursive(a, arr1, &len1);
// Get the postorder of b
int *arr2 = malloc(MAX_TREE_SIZE * sizeof(int));
int len2 = 0;
postorder_recursive(b, arr2, &len2);
int ret = 0; // 2 traversals are equal
if (len1 != len2) {
ret = 1;
} else {
for (int i = 0; i < len1; i++){
if (arr1[i] != arr2[i]){
ret = 1;
break;
}
}
}
free(arr1);
free(arr2);
return ret;
}
I have previously posted about this same topic. I am self-learning data structures using MIT Open Courseware. I'm doing the 6.S096-Introduction to C/C++ course and attempting the fourth assignment.
It is based on binary search trees and I gave it a try. I wanted to print the values for debugging but kept getting different executions each time.
One time, the cycle doesn't complete and the other time, it goes on to infinity. The debugging block also relates to the other function(find_node_data) I have to complete. So if I can figure what's wrong here, I can easily finish the find_node_data. I have commented a few things to see if it affects anything. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int node_id;
int data;
struct node* left;
struct node* right;
}node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node* newNode(int data,int node_id){
node* new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->node_id= node_id;
new_node->right= new_node->left=NULL;
return new_node;
}
node* insert_node(node* root, int node_id, int data) {
if(root==NULL)
return newNode(data,node_id);
else{
node* cur;
if(node_id<root->node_id){
cur=insert_node(root->left,data,node_id);
root->left=cur;
}
else if(node_id>root->node_id){
cur=insert_node(root->right,data,node_id);
root->right=cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*int find_node_data(node* root, int node_id) {
node* current;
for( current = root->; current->next!=NULL;
current= current->next){
if(current->data == data) return current;
}
return NULL;
}
*/
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T,data,node_id;
printf("Print yo cases");
scanf("%d", &T);
node* root = NULL;
while(T-->0){
printf("Type yo numnums no. %d:",T);
scanf("%d %d",&data,&node_id);
root=insert_node(root,data,node_id);
}
node *lol;
node *king;
for(lol=root;lol->left!=NULL;lol=lol->left){
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ",lol->node_id);//,king->node_id);
//}
}
return 0;
}
To find the node_data you can use recursion to find the node.
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
And then get the data for the node e.g. get the data for node with node_id 42:
printf("node data %d", find_node_data(root, 42)->data);
Full program below (I can't guarantee its correctness but maybe you can?)
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int node_id;
int data;
struct node *left;
struct node *right;
} node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node *newNode(int data, int node_id) {
node *new_node = (node *) malloc(sizeof(node));
new_node->data = data;
new_node->node_id = node_id;
new_node->right = new_node->left = NULL;
return new_node;
}
node *insert_node(node *root, int data, int node_id) {
if (root == NULL)
return newNode(data, node_id);
else {
node *cur;
if (node_id < root->node_id) {
cur = insert_node(root->left, data, node_id);
root->left = cur;
}
else if (node_id > root->node_id) {
cur = insert_node(root->right, data, node_id);
root->right = cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*
int find_node_data_old(node *root, int node_id) {
node *current;
for (current = root->; current->next != NULL;
current = current->next) {
if (current->data == data) return current;
}
return NULL;
}*/
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
void print(node *np) {
if (np) {
print(np->left);
printf("(%d, %d)", np->node_id, np->data);
print(np->right);
}
}
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d", find_node_data(root, 42)->data);
return 0;
}
Test
Print yo cases3
Type yo numnums no. 2:22 42
Type yo numnums no. 1:21 41
Type yo numnums no. 0:20 40
executed!
42 executed!
41 (40, 20)(41, 21)(42, 22)
node data 22
You may also use Jonathan Leffler's improved recursion to find the node:
node *find_node_data2(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else if (root->node_id > node_id)
return find_node_data(root->left, node_id);
else
return find_node_data(root->right, node_id);
}
Both functions return the correct values as seen in the second test.
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d\n", find_node_data(root, 42)->data);
printf("node data find_node_data2 %d", find_node_data2(root, 42)->data);
return 0;
}
Test 2
Print yo cases3
Type yo numnums no. 2:11 12
Type yo numnums no. 1:13 14
Type yo numnums no. 0:20 42
(12, 11)(14, 13)(42, 20)
node data 20
node data find_node_data2 20
This is my code,here I need to search a binary tree with the value x of type integer and need to return a pointer window of type BTREE of matching node.
Here programmes run into the case2,but still not searching for the node.I couldn't find my mistake.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct tree
{
int data;
struct tree *left;
struct tree *right;
}tree;
int AddToArray(tree *node, int arr[], int i);
tree *CreateNode(int data);
tree *Insert(tree *node, int data);
void PrintPreorder(tree *node);
int count(tree *node);
int compare(const void * a, const void * b);
//-------------------------------------------------------------------------------------------------
int main()
{
int i;
int choice;
int num;
int count;
int size;
int *arr=NULL;
tree *root=NULL;
while (1)
{
printf("enter your choice \n 1.Insert into tree \n");
printf("enter your choice \n 2.search element \n");
scanf("%d",&choice);
switch (choice)
{
case 1:
printf("Enter the input : \n");
scanf("%d",&num);
root = Insert(root, 4);
root = Insert(root, 3);
root = Insert(root, 5);
root = Insert(root, 10);
root = Insert (root, 8);
root = Insert (root, 7);
root = Insert(root,num);
break;
case 2:
printf("\n enter the element to be searched");
scanf("%d",&num);
for(i=0;i<100;i++)
{
if(arr[i]==num) {
printf("\n element found");
break;
}
}
if(i==count)
printf("\n element not found");
break;
}
printf("\n***BINARY TREE (PREORDER)***\n");
PrintPreorder(root);
}
}
/*intf("\n\n***ARRAY***\n");
arr = calloc(size, sizeof(int));
AddToArray(root, arr, 0);
qsort(arr,size,sizeof(int),compare);
for (i=0; i<size; i++)
{
printf("arr[%d]: %d\n", i, arr[i]);
}*/
//-------------------------------------------------------------------------------------------------
int compare(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int AddToArray(tree *node, int arr[], int i)
{
if(node == NULL)
return i;
arr[i] = node->data;
i++;
if(node->left != NULL)
AddToArray(node->left, arr, i);
if(node->right != NULL)
AddToArray(node->right, arr, i);
arr[i] = node->data;
i++;
}
tree *CreateNode(int data)
{
tree *node = (tree *)malloc(sizeof(tree));
node -> data = data;
node -> left = node -> right = NULL;
return node;
}
tree *Insert(tree *node, int data)
{
if(node==NULL)
{
tree *temp;
temp = CreateNode(data);
return temp;
}
if(data >(node->data))
{
node->right = Insert(node->right,data);
}
else if(data < (node->data))
{
node->left = Insert(node->left,data);
}
/* Else there is nothing to do as the data is already in the tree. */
return node;
}
void PrintPreorder(tree *node)
{
if(node==NULL)
{
return;
}
printf("%d ",node->data);
PrintPreorder(node->left);
PrintPreorder(node->right);
}
First of all allocate memory for arr
You are asking for binary tree but your code shows that you are using as if it is BST.[as for the add function].
Answer
If it is binary tree with no ordering then you have to search for all the nodes using standard tree traversal or BFS or DFS etc.
If it is `BST` then it will be easier.
1. Check the value x=root.val return root
2. else if( root.val> x) return search(x,root.left);
3. else return search(x,root.right);
One thing read about MCV example in SO. :)
Note 1: To allocate array you can have arr=malloc(sizeof(int)*n);
Note 2: If you are using array then you will store them this way
[ root root.left root.right root.left.left root.left.right root.right.left ... ]
1
/ \
2 3
/ \ / \
4 5 6 7
Note 3: Why are you using the array in this case..root can have access to any other node..if you don't want to dynamically allocate then only store them in a array otherwise you just dynamically insert necessary nodes when needed.
Code for searching in a BST (Binary Search Tree):
bool search(node * root, int x)
{
if(root->val==x)
return true;
else
{
if(x<root->val) //value is smaller go to the left subtree
return search(root->left,x);
else
return search(root->right,x);
}
}
Insertion algorithm BST
struct node* insert(struct node* node, int val)
{
if (node == NULL)
{
struct node *temp = malloc(sizeof(struct node));
temp->val = val;
temp->left = temp->right = NULL;
return temp;
}
if (val < node->val)
node->left = insert(node->left, val);
else if (val > node->val)
node->right = insert(node->right,val);
/* return the (unchanged) node pointer */
return node;
}
If you are using Binary tree
then you can also use some array [as we do in heap] or use a graph like structure (adjacency list..).
It is really upto your implementation.
Check this link for getting an idea - Binary tree implementation.
Searching in Binary tree
You can simply change the traversal code to this..
int levelOrder_Search(struct node* root)
{
struct Queue* queue = createQueue(SIZE);
Enqueue(root, queue);
while (!isEmpty(queue))
{
struct node* temp = Dequeue(queue);
if(temp->data==x)
return 1; // found :-)
if (temp->left)
Enqueue(temp->left, queue);
if (temp->right)
Enqueue(temp->right, queue);
}
return 0;//not found
}
Given a binary tree, I should visit starting from the leaves, in order to replace the value of each node with the sum of the values of its two child nodes. How should I proceed using a postorder visit?
The structure of each node is shown below.
struct node
{
int value;
struct node *left; // <- pointer to the left sub-tree
struct node *right; // <- pointer to the right sub-tree
};
Something like this?
void postorder_visit(struct node* root) {
int leftVal = 0;
int rightVal = 0;
if(root == NULL)
return;
postorder_visit(root->left);
postorder_visit(root->right);
//Don't want to change the leaves' values.
if(root->left == NULL && root->right == NULL)
return;
if(root->right != NULL)
rightVal = root->right->value;
if(root->left != NULL)
leftVal = root->left->value;
root->value = leftVal + rightVal;
}
The value at each node will be the sum of the values of its lChild and rChild.
EDIT
Edited to handle all integers (Have to do include limits.h to use INT_MAX)
int postOrder(struct node* node)
{
if(node == NULL)
{
return INT_MAX;
}
int x = postOrder(node->left);
int y = postOrder(node->right);
if(x != INT_MAX)
{
node->data = x;
}
if(y != INT_MAX)
{
node->data +=y;
}
return(node->data);
}
//Test code
void printinorder(struct node* node)
{
if(node == NULL)
{
return;
}
printinorder(node->left);
printf("%d\t",node->value);
printinorder(node->right);
}
int main()
{
struct node* root = newNode(10);
insert(root,5);
insert(root,-2);
insert(root,6);
insert(root,15);
insert(root,12);
insert(root,16);
printinorder(root);
printf("\n");
postOrder(root);
printinorder(root);
printf("\n");
}