Build a binary tree using two arrays given in C - c

I have a question. How can I add two arrays L(elements of theleft subtree) and D(elements of the right subtree) and create a binary tree? It's not a binary search tree. However these data that i have are stored in a file in which i have managed to convert the lines with numbers into int arrays S->Left elements and D->Right elements. Finally with the p i have stored the number of nodes from the first line. The file contains these lines:
7 ->Number of nodes
2 4 0 0 7 0 0 ->Left subtree elements
3 5 6 0 0 0 0 ->Right subtree elements
However my assignment is to build this code and do a postorder,inorder and preorder traversal of the binary tree and the output should look like this:
Preorder: 1 2 4 5 7 3 6
Inorder: 4 2 7 5 1 3 6
Postorder: 4 7 5 2 6 3 1
It's not clear for me why 1 is there. I am sure that 1 is the root but i don't know how to add the rest of the elements to the binary tree from S and D arrays.
My code so far looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int p;
int length1, length2, *S, *D;
int j = 0, k;
const char *v1;
const char *v2;
FILE *fptr = fopen("sd.in", "r");
if (fptr == NULL)
{
printf("Failed to open file\n");
return - 1;
}
char buf[3][100];
int i = 0;
while ((fgets(buf[i], 100, fptr) != NULL) && (i < 3))
{
printf("%s\n", buf[i++]);
}
fclose(fptr);
p = atoi(buf[0]);
v1 = buf[1];
v2 = buf[2];
length1 = strlen(v1);
length2 = strlen(v2);
S = (int*)malloc(length1 *sizeof(int));
D = (int*)malloc(length2 *sizeof(int));
while (sscanf(v1, "%d%n", &S, &length1) == 1)
{
printf(" element %d is %d\n", j, S);
v1 += length1;
j++;
}
while (sscanf(v2, "%d%n", &D, &length2) == 1)
{
printf(" element %d is %d\n", k, D);
v2 += length2;
k++;
}
printf("%d\n", p);
return 0;
}

Related

How can print numbers is separate lines?

The question to solve is that this code should get numbers in separate lines until 0 is given. Then it should print y number, y times. For example if number 3 is given, it should print 3, 3 times in separate lines.
I try to get the inputs from the user in separate lines. I mean one input in one line. Then print the numbers in separate lines. I don't know where to add \n to solve it.
This is my code:
#include <stdio.h>
int main() {
int y = 1;
while (y != 0) {
scanf("%d", &y);
if (y == (0)) {
break;
}
for (int i = 1; i <= y; i++) {
printf("%d\n", y);
}
}
}
I tried to add \n beside %d of scanf but it didn't work as I expected.
The output of this code is like this:
1
1
2
2
2
3
3
3
3
4
4
4
4
4
0
What I expect is that all the inputs should be given in separate lines before output is printed.
input like this:
1
2
3
4
0
output like this:
1
2
2
3
3
3
4
4
4
4
As #DavidC.Rankin explains below, if you want to retain the input it means you have to store it somewhere. It's usually in memory and either the original input string (char []) or you store the data in a format suitable for output like int input[LEN] that I use below.
Other options includes using a recursive function to store one number on the stack, or a file or an external service like a database (possible hosted in the cloud these days).
#include <stdio.h>
#define LEN 5
int main(void) {
// input
int input[LEN];
int i = 0;
for(; i < LEN; i++) {
if(scanf("%d",input + i) != 1) {
printf("scanf failed\n");
return 1;
}
if(!input[i])
break;
}
// output (copy of input other than 0)
for(int j = 0; j < i; j++) {
printf("%d\n", input[j]);
}
// output (repeated based on input)
for(int j = 0; j < i; j++) {
for(int k = 0; k < input[j]; k++) {
printf("%d\n", input[j]);
}
}
}
and example run:
1 # input
2
3
4
0
1 # output (copy of input other than 0)
2
3
4
1 # output (repeated based on input)
2
2
3
3
3
4
4
4
4
Here is the as close you can get with a recursive function and no arrays:
#include <stdio.h>
#include <stdlib.h>
void read_then_print() {
// input
int d;
if(scanf("%d", &d) != 1) {
printf("scanf failed\n");
exit(1);
}
if(d) {
// output before recursion
printf("%d\n", d);
read_then_print();
}
// output after recursion
for(int i = 0; i < d; i++) {
printf("%d\n", d);
}
}
int main(void) {
read_then_print();
}
and example session:
1 # input
1 # output before recursion
2 # input
2 # output before recursion
3 # ...
3
4
4
0
4 # output after recursion
4
4
4
3
3
3
2
2
1
#include<stdio.h>
int main()
{
int y;
do
{
scanf("%d",&y);
for(int i = 1;i <= y;i++)
{
printf("%d\n", y);
}
}while(y != 0);
}
Use this one this might solve your problem.
You want to gather all the input before processing the lines and printing the results. You can use an array to store the input numbers and process them once you read a 0.
Here is a modified version with this approach:
#include <stdio.h>
#define MAX_LINES 256
int main() {
int input[MAX_LINES];
int y, n = 0;
while (n < MAX_LINES && scanf("%d", &y) == 1 && y != 0) {
input[n++] = y;
}
for (int i = 0; i < n; i++) {
y = input[i];
for (int i = 0; i < y; i++) {
printf("%d\n", y);
}
}
return 0;
}

Code for Binary search in C not working properly

I can't fix the logical error because I don't know what is wrong in this code. Every input, it shows "element not found". I would really appreciate it if someone can help me in this. Also in this code, I have assumed we'll be taking the size of the array as an odd number, what to do if we decide to take an even number as size?
#include<stdio.h>
int main(){
int size;
printf("Enter the number of elemets(odd number) : ");
scanf("%d",&size);
int arr[size];
printf("Enter the elements in ascending order : ");
for(int i=0;i<size;i++){
scanf("%d",&arr[i]);
}
int element;
int flag=0;
printf("Enter element to be found : ");
scanf("%d",&element);
int low=0;
int high=size-1;
while(low<high){
int mid=(low+high)/2;
if(element<arr[mid]){
high=mid-1;
}
else if(element>arr[mid]){
low=mid+1;
}
else if(element==arr[mid]){
printf("Element %d found at pos %d ",element,mid);
flag=1;
break;
}
}
if(flag==0){
printf("Element not found");
}
return 0;
}
The problem is your while test. You have:
while(low<high) {
...
}
This will fail when low == high if the desired value is at that position. It is easily fixed by changing the test to:
while(low <= high) {
...
}
This is all that's needed to fix it. You don't need to add any special cases to "fix it up". Just make sure your array is in ascending order and it should work.
EDIT: Refer to the better answer by #TomKarzes
My old answer is:
You missed a boundary case of high==low
#include<stdio.h>
int main(){
int size;
printf("Enter the number of elements(odd number) : ");
scanf("%d",&size);
int arr[size];
printf("Enter the elements in ascending order : ");
for(int i=0;i<size;i++){
scanf("%d",&arr[i]);
}
int element;
int flag=0;
printf("Enter element to be found : ");
scanf("%d",&element);
int low=0;
int high=size-1;
while(low<high){
int mid=(low+high)/2;
if(element<arr[mid]){
high=mid-1;
}
else if(element>arr[mid]){
low=mid+1;
}
else if(element==arr[mid]){
printf("Element %d found at pos %d ",element,mid);
flag=1;
break;
}
}
if(low==high && arr[low]==element) //Added 1 extra condition check that you missed
{
printf("Element %d found at pos %d ",element,low);
flag=1;
}
if(flag==0){
printf("Element not found");
}
return 0;
}
For starters for the number of elements of the array you shell use the type size_t. An object of the type int can be small to accommodate the number of elements in an array.
This condition of the loop
int high=size-1;
while(low<high){
//...
is incorrect. For example let's assume that the array has only one element. In this case high will be equal to 0 and hence equal to left due to its initialization
int high=size-1;
So the the loop will not iterate and you will get that the entered number is not found in the array though the first and single element fo the array actually will be equal to the number.
You need change the condition like
while ( !( high < low ) )
//...
This if statement within the else statement
else if(element==arr[mid]){
is redundant. You could just write
else // if(element==arr[mid]){
It would be better if the code that performs the binary search will be placed in a separate function.
Here is a demonstrative program that shows how such a function can be written.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int binary_search( const int a[], size_t n, int value )
{
size_t left = 0, right = n;
int found = 0;
while ( !found && left != right )
{
size_t middle = left + ( right - left ) / 2;
if ( value < a[middle] )
{
right = middle;
}
else if ( a[middle] < value )
{
left = middle + 1;
}
else
{
found = 1;
}
}
return found;
}
int cmp( const void *a, const void *b )
{
int left = *( const int * )a;
int right = *( const int * )b;
return ( right < left ) - ( left < right );
}
int main(void)
{
const size_t N = 15;
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
size_t n = rand() % N + 1;
int a[n];
for ( size_t j = 0; j < n; j++ ) a[j] = rand() % N;
qsort( a, n, sizeof( int ), cmp );
for ( size_t j = 0; j < n; j++ )
{
printf( "%d ", a[j] );
}
putchar( '\n' );
int value = rand() % N;
printf( "The value %d is %sfound in the array\n",
value, binary_search( a, n, value ) == 1 ? "" : "not " );
}
return 0;
}
Its output might look for example the following way
0 2 2 3 4 5 7 7 8 9 10 12 13 13
The value 5 is found in the array
4 8 12
The value 10 is not found in the array
1 2 6 8 8 8 9 9 9 12 12 13
The value 10 is not found in the array
2 3 5 5 7 7 7 9 10 14
The value 11 is not found in the array
0 1 1 5 6 10 11 13 13 13
The value 7 is not found in the array
0 3 3 3 4 8 8 10 11 12 14 14 14 14
The value 3 is found in the array
0 5 5 10 11 11 12 13 13 14 14
The value 12 is found in the array
3 4 5 7 10 13 14 14 14
The value 14 is found in the array
0 3 3 7
The value 2 is not found in the array
1 6 9
The value 10 is not found in the array
2 2 3 3 4 4 4 5 5 6 8 8 9 13 13
The value 11 is not found in the array
11 11 13
The value 11 is found in the array
0 0 0 1 2 5 5 5 7 7 8 9 12 12 14
The value 6 is not found in the array
8 8 13
The value 1 is not found in the array
2 2 4 4 5 9 9 10 12 12 13 13 14 14
The value 14 is found in the array

Counting the number of elements of blocks with same consecutive elements

I'm having the following problem:
A park that have the form of a m x n board. There are k kinds of trees (1 <= k <= 100). The park is divided into m x n cells and each cell, they'll plant a tree. Now, on the map, each cell of the park have an integer i inside if the i-th kind of tree is planted in it, or a 0 if no tree is planted in it. A line of cells is considered "good" if it has at least t trees of same types, (and they must be on the same either line or column). Count the number of trees that is not in a "good" line.
Input: Integers m, n, t and an m x n array of integers represent the map.
Output: Number of trees that is not in a "good" line.
Example:
Input:
5 6 3
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
Output: 10
Explanation: The bold numbers are the trees that is not in a good line.
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
My idea is to check for each element in the array. If it is satisfied then I'll move to the nearest element outside the "good" line. Else, it will just move to the next element on the same line, or if the line is ended then the next element on the column.
Here is my code
#include <stdio.h>
#define maxn 120
int a[maxn][maxn], m, n, t;
int check(int *i, int *j){
int k, cnt_r, cnt_c;
cnt_r = 0;
//jump to the nearest cell that is not in good line
for(k = *i + 1; k < m; k++){
if(a[*i][*j] == a[k][*j]) cnt_r++;
if(cnt_r >= t){
*i = k;
return 1;
}
}
cnt_c = 0;
for(k = *j + 1; k < n; k++){
if(a[*i][*j] == a[*i][k]) cnt_c++;
if(cnt_c >= t){
*j = k;
return 1;
}
}
return 0;
}
//check if this is the last square or not
int lastSq(int r, int c){
return (r == n - 1 && c == n);
}
int main(){
int res = 0, i, j, pos_r = 0, pos_c = 0;
scanf("%d%d%d", &m, &n, &t);
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
scanf("%d", &a[i][j]);
while(!lastSq(pos_r, pos_c)){
if(a[pos_r][pos_c] == 0){
if(pos_c < n - 1) pos_c++;
else if(pos_r < n - 1){
pos_c = 0;
pos_r++;
}
}
if(!check(&pos_r, &pos_c)){
res++;
if(pos_c < n - 1) pos_c++;
else{
pos_c = 0;
pos_r++;
}
}
}
printf("%d", res);
}
But it doesn't print any output. The only thing I have is 0xC0000005. Can someone please check where did I make a mistake and provide me a direction? Thanks.

Serial numbers of equal numbers next to each other in array

#include <stdio.h>
void main(){
int i, j, n;
int num[5];
int serial;
for(i=0; i<5; ++i){
scanf("%d",&num[i]);
if(num[i]==num[i-1])
serial=i;
else
continue;
}
printf("Serial number of equal numbers next to each other:%d. %d.", serial-1, serial);
}
This may be hard to understand because I'm not a native English speaker.
If the numbers next to each other are equal the program should print the serial number of those numbers.
For example:
Input: 1 2 3 7 7 7 6;
Output: 3. 4. 5.
Input: 5 5 5 5 5
Output: 0. 1. 2. 3. 4.
I made some changes now it prints the serial of two equal numbers.
I: 1 2 2 3 4 - O: 1. 2.
But what if all the numbers are equal?
// ...
// deal with index 0
if (num[0] == num[1]) printf("0. ");
// deal with indexes 1 .. N - 2
for (int k = 1; k < n - 1; k++) {
if ((num[k - 1] == num[k]) || (num[k] == num[k + 1])) {
printf("%d. ", k);
}
}
// deal with index N - 1
if (num[n - 2] == num[n - 1]) printf("%d. ", n - 1);
// ... possibly with a printf("\n"); somewhere
You can solve this without storing the numers in an array, but you must keep track of how many equal numbers have been read before reading the present one:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i = 0; // running index
int prev = 0; // previously read number
int iprev = 0; // start of range of equal numbers previously read
int n; // currently read number
while (scanf("%d", &n) == 1) {
if (n != prev) {
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
iprev = i;
prev = n;
}
i++;
}
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
return 0;
}
You consider stretches of equal numbers only after you read a number that terminates the current range of equal numbers. When all numbers are different, the size of that range is 1 and we don't print anything. If the range is larger than 1, print all indices in question.
Because you don't notice a change after reading the last number, you must check the last range separately after the main loop.
If you can put a non-numeric character in the [0] element of your array, you won't need a different test for the first element
int main (void)
{
/* non-numeric in position 0 of data array */
char myList[] = {'.','1','2','2','3','4','4','4','5','6','6'};
int listSz = strlen(myList) -1;
int n;
/* check everything except last */
for (n = 1; n < listSz; n++) {
if(( myList[n] == myList[n +1]) || ( myList[n] == myList[n -1] )) {
printf("%d . ", n);
}
}
/* check last */
if( myList[listSz] == myList[listSz -1] ) {
printf("%d", n);
}
printf("\n");
}
Output: 2 . 3 . 5 . 6 . 7 . 9 . 10

Need help for find the logic of a heuristic sequence

I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
0 1
2 3 4 5
6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

Resources