Binary tree, print out which level I am on - c

I want to print out into my sorted tree on which level this number was and that must be a recursion function.
Here is my code:
void printout(KNOTEN *start) {
if (start == NULL)
return;
printout(start->left);
printf("%d\n", start->number);
printout(start->right);
free(start);
}
Here is an example of the output:
My input Numbers 41, 18467, 6334 , 26500, 19169
Outprint is 41,6334,18467,19169,26500
What I want is:
41 Level 1 , 6334 level 3 , 18467 level 2 , 26500 level 3 , 19169 level 4

I would modify it to this:
void printout(KNOTEN *start, int depth)
{
if(start == NULL)
return;
printout(start->left, depth+1);
printf("%d(%d) \n",start->number, depth);
printout(start->right, depth+1);
free(start);
}

here is a hint. your prototype is this
printout(KNOTEN *start, int the_level)
and this is how you call it to start your search.
printout(node, 1);
and there is a the_level + 1 in two places in your code.
good luck

This sounds like homework, so I'm not going to give you complete code. But the idea is to keep count of how many recursive calls you've made:
int myRecursiveFunction(Node *node, int thingToFind, int level)
{
if (someCondition())
{
return level;
}
else
{
if (goLeft())
{
return myRecursiveFunction(node->left, thingToFind, level+1);
}
else
{
return myRecursiveFunction(node->right, thingToFind, level+1);
}
}
}
...
int level = myRecursiveFunction(root, thingToFind, 0);

Related

Recursive function to represent binary tree in C

Problem
I want to print the nodes of a binary tree inorder and would like to have the nodes printed with as many dashes as the height they are in and then it's data.
Research done
I have found other posts like this one or this one but I'm still clueless on how I can represent my binary tree the way I want, as it differs to the ones stated on those questions.
Example
So lets say I insert nodes with data in this manner:
5,4,2,3,9,8
The output I would expect when representing the binary tree would be:
-9
--8
5
-4
---3
--2
Toy example code
So far I was able to print the nodes in the correct order. But after days I'm still clueless on how to implement a recursive function to get the correct representation. I also tried loops but found it's even messier and wasn't getting the correct result either.
The problem is that the amount of dashes is not the correct one and I'm unsure on where I need to append the dashes within the recursion. I'm thinking I may need to rewrite the whole printBinaryTreeRecurrsively code.
Below you can see the toy example code which can be compiled as a whole:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct repBinaryTree *BinaryTree;
struct repBinaryTree {
int data;
BinaryTree left;
BinaryTree right;
};
BinaryTree newNode() {
BinaryTree b = new repBinaryTree;
b->data = NULL;
b->left = b->right = NULL;
return b;
}
BinaryTree insertNode(int i, BinaryTree b) {
if (b==NULL) {
b = newNode();
b->data = i;
} else if ( i < b->data ) {
if (b->left == NULL) {
b->left = newNode();
b->left->data = i;
} else {
insertNode(i, b->left);
}
} else if ( i > b->data ) {
if (b->right == NULL) {
b->right = newNode();
b->right->data = i;
} else {
insertNode(i, b->right);
}
}
return b;
}
char* printBinaryTreeRecurrsively(BinaryTree b, char level[]) {
if (b == NULL) {
printf("\n");
return level;
} else {
level = printBinaryTreeRecurrsively(b->right, level);
printf("%s%d",level,b->data);
level = printBinaryTreeRecurrsively(b->left, level);
}
strcat(level,"-");
return level;
}
int main () {
BinaryTree b = insertNode(5,NULL);
b = insertNode(4, b);
b = insertNode(2, b);
b = insertNode(3, b);
b = insertNode(9, b);
b = insertNode(8, b);
printf("Recursive BinaryTree print:");
char level0[] = "";
printBinaryTreeRecurrsively(b, level0);
printf("Expected BinaryTree print:");
printf("\n-9\n--8\n5\n-4\n---3\n--2\n");
}
The output I get after compiling and running the program from command line is as follows:
cedric#multivac:~$ g++ printBinaryTree.cpp -o printBinaryTree
cedric#multivac:~$ ./printBinaryTree
Recursive BinaryTree print:
9
8
--5
--4
--3
---2
Expected BinaryTree print:
-9
--8
5
-4
---3
--2
Question
How should I rewrite my printBinaryTreeRecurrsively function code so as I get the correct output?
Modify the function to this instead
void printBinaryTreeRecurrsively(BinaryTree b, int level) {
if (b == NULL) {
printf("\n");
} else {
printBinaryTreeRecurrsively(b->right, level+1);
for (int i = 0; i < level; i++) {
printf("-");
}
printf("%d",b->data);
printBinaryTreeRecurrsively(b->left, level+1);
}
}
and call in main() as
printBinaryTreeRecurrsively(b, 0);
This method is much simpler than worrying about string concatenation etc. Just keep track of which level you're on with an int, print the correct number of -, and tell the levels below to print with one more -.

C function that creates a linked list with "divisible by 3" numbers from another linked list

First, I need to create and show a list that ends with number 1000. That works well.
Then, I want to create another list with only the numbers that are divisible by 3 in the first list, but it doesn't work.
The worst thing is that it doesn't even tell me what's going on. It just gives error in the execution but the console doesn't say anything.
I will really appreciate any help.
I tried all.
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define CANTIDAD_NUMEROS 13
#define CANTIDAD_NUMEROS2 6
#define DESDE 1
#define HASTA 10
typedef struct lista{
int num;
struct lista *sig;
}nodo;
void crear (nodo *pt, int, int);
void crear2 (nodo *pt, int, nodo *pt2);
void mostrar(nodo *pt);
int main()
{
int i=0;
int t=0;
nodo *prin;
nodo *prin2;
prin=(nodo*)malloc(sizeof(nodo));
prin2=(nodo*)malloc(sizeof(nodo));
crear(prin,i, t); //creates first list
mostrar (prin); //shows first list
crear2(prin,i, prin2); //gets 'divisible by 3' numbers
mostrar(prin2); // shows second list
return 0;
}
//creates list
void crear (nodo *registro, int cont, int t)
{
scanf("%d", &t);
registro->num = t;
if (registro->num == 1000)
registro->sig=NULL;
else
{
registro->sig=(nodo*)malloc(sizeof(nodo));
cont++;
crear (registro->sig,cont, t);
}
return;
}
//shows list
void mostrar (nodo *registro)
{
if (registro->sig !=NULL)
{
printf ("%d\n",registro->num);
mostrar (registro->sig);
}else{
printf("%d\n",registro->num);
}
return;
}
//creates second list with only numbers that are divisible by 3
void crear2 (nodo *registro, int cont, nodo *registroNuevo)
{
if ((registro->num % 3) == 0){
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
}
if(registro->sig != NULL){
crear2(registro->sig,cont, registroNuevo->sig);
}else{
return;
}
}
I expect to have the 1st list shown (which it's happening) and also the 2nd list shown with the numbers that are divisible by 3, which doesn't happen.
First of all, I admire your dedication to recursion!
The problem is that in crear2, registroNuevo->sig is uninitialized which causes a segfault. I almost always start a function that operates on a recursive linked data structure by checking if the parameter node is null. If so, I can safely continue on with the body of the function. Following this logic of protecting against nulls, we need to pass the registroNuevo node along without touching it in the case when registro->num % 3 != 0 and ensure all of its fields are initialized.
Here's the corrected function:
void crear2(nodo *registro, int cont, nodo *registroNuevo)
{
if (registro) {
if (registro->num % 3 == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = NULL;
if (registro->sig) {
registroNuevo->sig = malloc(sizeof(nodo));
}
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
crear2(registro->sig, cont, registroNuevo);
}
}
}
Having said that, this function is still a bit less than ideal for a couple reasons. First of all, the name is vague and could describe the behavior better. Also, if there are no items divisible by three, you've got a malloced node back in the calling scope that never gets initialized, so it's a bit brittle in that regard. Thirdly, even with a parameter, it feels like a highly specific function without much reusability factor that could be written iteratively inside the calling scope like:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo
{
int num;
struct nodo *sig;
} nodo;
nodo *crear(nodo *registro, int num)
{
nodo *n = malloc(sizeof(nodo));
n->num = num;
n->sig = registro;
return n;
}
void mostrar(nodo *registro)
{
if (registro)
{
printf("%d->", registro->num);
mostrar(registro->sig);
}
else puts("");
}
void free_lista(nodo *registro)
{
if (registro)
{
free_lista(registro->sig);
free(registro);
}
}
int main()
{
nodo *prin = NULL;
nodo *prin_div_3 = NULL;
for (int t; scanf("%d", &t) && t != 1000;)
{
prin = crear(prin, t);
}
nodo *tmp = prin;
while (tmp)
{
if (tmp->num % 3 == 0)
{
prin_div_3 = crear(prin_div_3, tmp->num);
}
tmp = tmp->sig;
}
mostrar(prin);
mostrar(prin_div_3);
free_lista(prin);
free_lista(prin_div_3);
return 0;
}
This isn't perfect--without tail nodes, adding to the list is a bit less than ideal, but dangling heads are eliminated, and hopefully it shows an alternate approach to organizing program logic and functions.
A few other remarks:
Always free memory that you've allocated. You can write a simple recursive routine to do so, like free_lista as shown in the above example.
Consider avoiding highly specific functions with hard-coded values like 3 and 1000. Make these parameters to maximize reusability.
crear2 never uses the cont member, and you have global constants that are unused. It's a good idea to clean these up to help clarify your debugging efforts and reduce visual clutter.
No need to cast the result of malloc.
if (registro->sig !=NULL) as the first line of a function is going to crash on a null. You don't need != NULL either. if (registro) { ... } is clearest and avoids problems with null parameters.
void crear2 (nodo *registro, int cont, nodo *registroNuevo) {
if ((registro->num % 3) == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo);
}
}
This is my approach, but you are still getting a final unexpected 0 at the last mostrar() call; and you still need to do the 'free' calls. I think you should avoid the recursive calls, there are easier ways to do it. Saludos.

COUNT BST subtrees until finding specific given key (inorder traversal)

Homework assignment
I need to count how many subtrees I went through (inorder) until found the given key,
for example: if I have a tree, & it's inorder traversal is: 1,3,7,8,9,10,11,15,20
when given key:9, I need to return 5, when given key:3, I need to return 2.
I have been all over the internet trying to find some help & couldn't find.
What I got so far is:
(The "FUNC" is a specific function that compares integers or whatever, it works)
void PRINT_KEY_ORDER(PTN TRoot, void *nkey, CMP_KEYS FUNC) // prints keys place (inorder)
{
int counter = 1;
fprintf(stdout, "%d", *(COUNT_INORDER(TRoot, nkey, FUNC, &counter))); // prints counter which is always INT
}
int* COUNT_INORDER(PTN TRoot, void *nkey, CMP_KEYS FUNC, int *counter) // counts times until reaches wanted key
{
if (TRoot != NULL)
{
COUNT_INORDER(TRoot->left, nkey, FUNC, counter);
if (FUNC(TRoot->key, nkey) == 0)
return counter;
(*counter)++;
COUNT_INORDER(TRoot->right, nkey, FUNC, counter);
}
}
this code works.
Counts correctly but for some reason crashes on the fprintf line if I use more than these: 9 3 1 7 8 20
Not sure if this is correct. Try to go inorder and increase count in a static variable. Once key is found put that as the return variable, otherwise the default return is -1 for key not found.
int COUNT_INORDER(PTN TRoot, nkey, FUNC )
{
static count=0;
int ret=-1;
ret= COUNT_INORDER(TRoot->left, nkey, FUNC);
count++;
if (FUNC(TRoot->key, nkey) == 0)
ret = count;
if(ret == -1)
ret= COUNT_INORDER(TRoot->right, nkey, FUNC);
return ret;
}

Unable to create Adjacency List for an undirected Graph using C

I'm faced with a problem which I've been unable to tackle for quite some time.
I've been given a graph as follows,in a M x N matrix:
2 2
a b
a c
Note
I've interpreted the graph above as a matrix,only consisting of non-diagonal edges.
Here the first line represents values of M and N respectively.
The graph is only connected either along vertical,or adjacent direction,i.e.,up,down,left and right. diagonal edges not present.
In order to find the adjacency list of the graph(the desired output here):
a-b-c
b-a-c
c-a-b
Steps followed by me in the code:
1.Read M x N matrix into a 2D array.
2.Created a list of unique vertices of the graph as Unode[arrmax].
3.For each element of the matrix,if the character matches with an element of the unique vertices list,I've called the modify Adjacency List procedure that searches the neighbours of the concerned matrix vertex and populates/appends to the the Adjacency list if distinct nodes are found.
It takes as arguments, i,j,M,N,AdjList,number of elements in the list and makes the changes.
5.I've kept the list of nodes to be global for easy modification.
6.Next I intend to use the adjacency list produced to use in DFS procedure and find the DFS forest.
The Problem statement:
the input consists of a grid of size M X N. Each cell in the grid
contain a lower case letter of the English alphabet.In a natural way,
the cells are of two types: boundary cells and internal cells. Each
internal cell in the grid has four neighbours in one of the left,
right, top, down directions. A string of characters can be formed by
starting at any cell and traversing the grid through the neighbours.
You have to print all the possible strings subject to the following
constraints:
**No two characters in a string can be same
**No two strings can be same in the final output
**The strings should be printed in alphabetically sorted order.
INPUT:
First line contains two integers M and N
Next M lines contains N space separated characters each
OUTPUT:
Print all possible strings in sorted order and obeying the above constraints.
INPUT SIZE:
1 <= M, N <= 20
SAMPLE INPUT:
2 2
a b
a c
SAMPLE OUTPUT:
a ab abc ac acb b ba bc bca c ca cb cba
[UPDATE]:
Completely redesigned the code,used structures for the graph nodes,and one for handling indices.
Yet the result I'm getting:
a--b-a
b--a
a
c--a
My code[Relevant Portion]:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define ADJMAX 20
#define arrmax 400
typedef struct uniq_node{
char ch;
char AdjList[ADJMAX];
int numofelem;
int visited;
}unode;
unode Ulist[arrmax];
int uniq_tot=0;
typedef struct index
{
int i,j;
}Ind;
Ind indx;
int charcomp(char sch,char arr[],int arrlim);
void adjModify(unode*,char*,int,int,Ind);
int chIndex(int,int,int,int);
int main(void) {
int mvar,nvar;
char str[15],*token;
long integer;
/*To scan the values of M & N*/
scanf("%d %d\n",&mvar,&nvar);
int iter,iterv,jterv;
/*To create the character matrix of M x N*/
char cmat[mvar][nvar];
/*Initializing the unique nodes list*/
/*To read-in the matrix from the stdin:-A LOT OF HARD WORK*/
for(iterv=0;iterv<mvar;iterv++)
{
fgets(str,50,stdin);
jterv=0;
token=strtok(str," ");
while(token)
{
/*Assigning value to the character matrix*/
cmat[iterv][jterv]=*token;
/*Code to populate the list of unique elements*/
if(charcomp(*token,Ulist[uniq_tot].AdjList,uniq_tot)==3)
{
Ulist[uniq_tot].ch=*token;
uniq_tot++;
Ulist[uniq_tot].numofelem=1;
Ulist[uniq_tot].AdjList[0]=*token;
//Ulist[uniq_tot].visited=0;
}
jterv++;
token = strtok(NULL, " ");
}
}
/*To populate the adjacency lists */
char ch;
for(iterv=0;iterv<mvar;iterv++)
{
for(jterv=0;jterv<nvar;jterv++)
{
ch=cmat[iterv][jterv];
indx.i=iterv;
indx.j=jterv;
for(iter=0;iter<uniq_tot;iter++)
{
if(ch==Ulist[iter].ch)
break;
}
adjModify(&Ulist[iter],(char*)cmat,mvar,nvar,indx);
}
}
/*for(iter=0;iter<uniq_tot;iter++)
{
printf("%c",Ulist[iter].ch);
printf("\n%s\n",Ulist[iter].AdjList);
for(iterv=0;iterv<Ulist[iter].numofelem;iterv++)
{
printf("-%c",Ulist[iter].AdjList[iterv]);
}
printf("\n");
}*/
return 0;
}
int chIndex(int i,int j,int mvar,int nvar)
{
return (i>=0 && i<mvar && j>=0 && j<nvar);
}
void adjModify(unode* Unode,char* mat,int mvar,int nvar,Ind mind)
{
int idum,jdum;
if(chIndex(mind.i,mind.j-1,mvar,nvar))
{
idum=mind.i;
jdum=mind.j-1;
if(charcomp(*(mat+idum*nvar+jdum),Unode->AdjList,Unode->numofelem)==3)
{
++Unode->numofelem;
Unode->AdjList[Unode->numofelem]=*(mat+idum*nvar+jdum);
printf("\nI'm here in coord:(%d,%d), with element: %c, and AdjList: %s for character: %c",idum,jdum,*(mat+idum*nvar+jdum),Unode->AdjList,Unode->ch);
}
}
if(chIndex(mind.i,mind.j+1,mvar,nvar))
{
idum=mind.i;
jdum=mind.j+1;
if(charcomp(*(mat+idum*nvar+jdum),Unode->AdjList,Unode->numofelem)==3)
{
++Unode->numofelem;
Unode->AdjList[Unode->numofelem]=*(mat+idum*nvar+jdum);
printf("\nI'm here in coord:(%d,%d), with element: %c, and AdjList: %s for character: %c",idum,jdum,*(mat+idum*nvar+jdum),Unode->AdjList,Unode->ch);
}
}
if(chIndex(mind.i-1,mind.j,mvar,nvar))
{
idum=mind.i-1;
jdum=mind.j;
if(charcomp(*(mat+idum*nvar+jdum),Unode->AdjList,Unode->numofelem)==3)
{
++Unode->numofelem;
Unode->AdjList[Unode->numofelem]=*(mat+idum*nvar+jdum);
printf("\nI'm here in coord:(%d,%d), with element: %c, and AdjList: %s for character: %c",idum,jdum,*(mat+idum*nvar+jdum),Unode->AdjList,Unode->ch);
}
}
if(chIndex(mind.i+1,mind.j,mvar,nvar))
{
idum=mind.i+1;
jdum=mind.j;
if(charcomp(*(mat+idum*nvar+jdum),Unode->AdjList,Unode->numofelem)==3)
{
++Unode->numofelem;
Unode->AdjList[Unode->numofelem]=*(mat+idum*nvar+jdum);
printf("\nI'm here in coord:(%d,%d), with element: %c, and AdjList: %s for character: %c",idum,jdum,*(mat+idum*nvar+jdum),Unode->AdjList,Unode->ch);
}
}
}
/*Comparison routine*/
int charcomp(char fchar,char arr[],int ucindex)
{
int ivar;
for(ivar=0;ivar<ucindex;ivar++)
{
if(arr[ivar]==fchar)
return;
}
return 3;
}
I think you can skip creating individual nodes for every element in the 2D array. Having the 2D array implies a structured connectivity. When it starts getting large, traversing all these elements may become cumbersome.
My recommended approach would be the following:
Scan of the matrix and pull unique nodes. i.e. start with a scan and have the simple list a,b,c (you'll need to sort them).
Create a struct for each unique node consisting the number of paths you currently have and an array of char arrays to store each one in. i.e. char** myArray={{a},{ab},{abc},{ac},{acb}} would be the one for a (This is of course unknown when you start).
Loop through your unique nodes, and one by one find the location in the 2D array. Don't save them, just go through them one by one and do a scan function to look for all their paths.
The scan function should be recursive so it can go as far as it needs to while checking every possible path (recursive will help you check every direction at every node you traverse). Keep track of where you've been, and at ever step check that you have not already encountered that character.
When you can't go any further, make sure the string has not already been included, if it has continue to the next path, if not add it to the list.
this is my code in c++ without any library that can work in c but you just have to use in c printf instead of cout and instead of class use struct that's all. I also write code for breadth first traversal see below.
and include the header file also
// #include <stdio.h>
//#include<stdlib.h>
#include<iostream
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data) {
this->data=data;
this->next=NULL;
// cout<<"from node file"<<endl;
}
};
class Queue {
Node * head;
Node * tail;
int length;
public:
Queue() {
head=NULL;
tail=NULL;
length=0;
}
bool isEmpty() {
return length==0;
}
int size() {
return length;
}
int front() {
if(head==NULL) {
cout<<"Empty Queue"<<endl;
return 0;
}
return head->data;
}
void enqueue(int element) {
Node * newNode =new Node(element);
if(head==NULL) {
head=newNode;
tail=newNode;
}else{
tail->next=newNode;
tail=newNode;
}
length++;
}
int dequeue() {
if(head==NULL) {
cout<<"Empty queue"<<endl;
return 0;
}
int output= head->data;
Node * temp=head;
head=head->next;
temp->next=NULL;
delete temp;
length--;
return output;
}
};
class AdjList{
public:
Node * head;
AdjList() {
head=NULL;
//cout<<"from adlist"<<endl;
}
void add (int data) {
Node * newNode=new Node(data);
if(head==NULL) {
head=newNode;
}else {
Node* temp=head;
while(temp->next!=NULL) {
temp=temp->next;
}
temp->next=newNode;
}
}
};
class Graph{
public:
int v;
AdjList* adjList;
Graph(int v) {
this->v=v;
adjList=new AdjList[v];
}
void addEdge(int src, int dest) {
adjList[src].add(dest);
///for bidrectional add below code
//adjList[dest].add(src);
}
void print(){
for(int i=0;i<v;i++){
Node *temp = adjList[i].head;
cout << i << " -> ";
while(temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
}
void bfs(int src) {
// using a queue also in this file how to add queue structure
Queue q;
bool* visited=new bool [v]{0};
q.enqueue(src);
visited[src]=true;
while(!q.isEmpty()) {
int node= q.front();
cout<<node<<" ";
q.dequeue();
Node *temp = adjList[node].head;
while(temp!=NULL){
if(!visited[temp->data]) {
q.enqueue(temp->data);
visited[temp->data]=true;
}
// cout<<"data "<<temp->data;
temp=temp->next;
/// how to traverse
}
}
}
};
int main(){
Graph g(6);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(2, 3);
g.addEdge(3,4);
g.addEdge(4,5);
g.bfs(0);
// g.print();
return 0;
}

Pre/In/Postfix traversal in C including an Array

I would like to implement functions where I perform a pre, in and postorder traversal of an existing binary tree.
these traversals should then be displayed by a predefined test function
here's what i got so far for the preorder traversal
uint64_t i = 0;
int *binarytree_prefix(binarytree *tree) {
uint64_t *prefixArray = malloc(inputArrayLength_helper * sizeof(uint64_t));
prefixArray[i] = tree->value;
i++;
if (tree->left != NULL) {
return (binarytree_prefix(tree->left));
}
if (tree->right != NULL) {
return (binarytree_prefix(tree->right));
}
}
what I thought about it that it would insert the value of the current node into the array and then increent the position within the array and do a recursion on the left and then the right tree
however this does not work.
i hope someone is able to help me to make it running
What i did was a depth first search with a preorder traversal and then included the array to fill it with the current value
test function within main:
int *prefixArray = bintree_prefix(tree);
printf("Prefix notation : ");
for(uint64_t i = 0; i < inputArrayLength; i++) {
printf(" %d", prefixArray[i]);
}
printf("\n");
free(prefixArray);
ok after a few different variations of the code i finally got the right solution
for those interested
int *bintree_prefix(bintree *tree)
{
int *prefixArray = malloc(17*sizeof(uint64_t));
return (bintree_prefix_visited(tree, prefixArray));
}
int bintree_prefix_visited(bintree *tree, int *prefixArray)
{
if (tree!=NULL)
{
prefixArray[a]=tree->value;
a++;
bintree_prefix_visited(tree->left, prefixArray);
bintree_prefix_visited(tree->right, prefixArray);
}
return prefixArray;
}

Resources