Printing the nodes of a tree - c

I have a k-ary tree represented like that:
struct node {
int num;
int data;
struct node **kids;
}
I have created a function in order to print the data of the nodes of the tree.
Example:
a
/ | \
b c d
/
e
will print:
a
b
e
c
d
The function is:
void visit(struct node *head){
int i;
if (head == NULL)
return;
printf("%d\n", head->data);
for (i = 0; i < head->num; i++)
visit(head->kids[i]);
}
Question is, how can I also print the level of each node that i print. I tried to declare a variable int level = 0; and increment it but it won't work because the recursive call resets it.

void visit(struct node *head){
static int i;
if (head == NULL)
return;
printf("%d\n", head->data);
printf("Level : %d\n",i);
for (i = 0; i < head->num; i++)
visit(head->kids[i]);
i = i + 1;
}

Pass another parameter to recursive function
void visit(struct node *head, int level){
int i;
if (head == NULL)
return;
printf("%d : %d\n",level, head->data);
for (i = 0; i < head->num; i++)
visit(head->kids[i], level + 1);
}
And first time, invoke the function by passing level as zero.

Related

How do implement Count sort using linked list?

What I am trying to do is to create a counting sort using a linked list so I can link two similar elements in the same index and then copy from left to right to the original array. But my Buckets[i] are always NULL even after insertion. So my resulting array does not change. I don't know what I am doing wrong.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
} **Buckets;
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
int findMax(int A[], int n) {
int i, max = A[0];
for (i = 0; i < n; i++) {
if (A[i] > max)
max = A[i];
}
return max;
}
void Insert(struct Node *p, int x) {
while (p != NULL) {
p = p->next;
}
Node *t = t = (struct Node *)malloc(sizeof(struct Node));
t->data = x;
t->next = NULL;
p = t;
}
int Delete(struct Node *Buckets) {
while (Buckets->next != NULL) {
Buckets = Buckets->next;
}
int temp = Buckets->data;
free(Buckets);
return temp;
}
void BucketSort(int A[], int size) {
int max, i, j;
max = findMax(A, size);
Buckets = new Node * [max + 1];
for (i = 0; i < max + 1; i++) {
Buckets[i] = NULL;
}
for (i = 0; i < size; i++) {
Insert(Buckets[A[i]], A[i]); //insertion
}
i = j = 0;
while (i < max + 1) {
while (Buckets[i] != NULL) {
A[j++] = Delete(Buckets[i]); // copy back in array
}
i++;
}
}
int main() {
int arr[] = { 3, 8, 5, 1, 10 };
int size = sizeof(arr) / sizeof(arr[0]); //5
printf("\nBefore : ");
printArray(arr, size);
BucketSort(arr, size);
printf("\nAfter : ");
printArray(arr, size);
return 0;
}
Your Insert function doesn't really modify the list – you just assign the new node to a local variable, which goes out of scope immediately.
You can solve this by passing a pointer to a node pointer to the function. That pointer points at the head pointer at first and at the next member of the preceding node when you advance:
void Insert(struct Node **p, int x)
{
while (*p) p = &(*p)->next;
*p = new Node(x); // assume a c'tor here
}
Call the function like so:
for (i = 0; i < size; i++) {
Insert(&Buckets[A[i]] ,A[i]);
}
The same goes for deletion: You must modify the links or the list head when you delete:
int Delete(struct Node **p)
{
int temp = (*p)->data;
struct Node *del = *p;
*p = (*p)->next;
delete del;
return temp;
}
(This code extracts the head node, which is probably what you want: You insert at the end, then retrieve from the beginning. That should preserve the original order. Not that it matters miuch in your case, where you have no data beside the int.)
Call Delete like so:
i = j = 0;
while (i < max + 1) {
while (Buckets[i]) {
A[j++] = Delete(&Buckets[i]);
}
i++;
}

Why is my code giving me garbage values and sometimes segmentation fault?

I'm trying to make an implementation of merge() given 2 sorted linked lists, and output a linked list that merges the two and is sorted. I first create an array and put the items there, but when I print the array elements I get garbage values/seg fault. I know it's a lot of code to go through but I'd really appreciate anyone who can help :)
typedef struct _node {
int data;
struct _node * next;
} node_t;
typedef struct {
node_t * head;
node_t * tail;
} LL_t;
LL_t* createList(int num_nodes);
void printList(LL_t* L);
void merge(LL_t * L, LL_t * L2);
void merge(LL_t * L, LL_t * L2){
if(L2->head==NULL){ // empty L2
free(L2);
return;
}
else if(L->head==NULL){ // empty L1
*L=*L2;
free(L2);
return;
}
node_t* node=L->head;
int mid=0;
if(node->next!=NULL){
for (mid=0; node->next!=NULL; mid++) //finds last index of L1
node=node->next;
}
L->tail->next=L2->head;
L->tail=L2->tail;
node_t* ind = L->head;
free(L2);
int len=0;
for (len=0; ind!=NULL; len++) // finds num of items in list
ind=ind->next;
int arr[len];
int newarr[len];
node_t* cur= L->head;
for(int i=0; cur!=NULL; i++){ // creates array with list items
arr[i]=cur->data;
cur=cur->next;
}
int first=0;
int last=len;
int leftpos=0;
int rightpos=mid+1;
int newpos=0;
// insert elements to arr until a half of the array
// reaches mid or last
while(leftpos<=mid && rightpos<=last-1){
if(arr[leftpos]<arr[rightpos]){
newarr[newpos++]=arr[leftpos++];
}
else
newarr[newpos++]=arr[rightpos++];
}
// fills in the rest of the array
while(leftpos<=mid)
newarr[newpos++]=arr[leftpos++];
while(rightpos<=last)
newarr[newpos++]=arr[leftpos++];
for(int j=0; j<len; j++)
printf("newarr=%d\n",newarr[j]);
}
int main(void){
int num_nodes = 4;
int num_nodes2 = 3;
LL_t* L=createList(num_nodes);
LL_t* L2=createList(num_nodes2);
merge(L, L2);
}
// Creates the list. No problem here
LL_t* createList(int num_nodes){
LL_t* L = malloc(sizeof(LL_t));
L->head=NULL;
L->tail=NULL;
node_t *n;
int i=0;
for (i = 0; i < num_nodes; i++) {
n = malloc(sizeof(*n));
scanf("%d",&n->data);
n->next = NULL;
if (L->head == NULL){
L->head = n;
L->tail = n;
}
else {
L->tail->next = n;
L->tail = n;
}
}
puts("\n");
return L;
}
The problem is here in the merge():
while(rightpos<=last)
newarr[newpos++]=arr[leftpos++];
^^^^^^^
Here, the condition of while loop is rightpos<=last but accessing leftpos index element of arr and incrementing it. And if rightpos is less than last then the while loop condition will always be true which makes it an infinite loop. Every iteration of while loop is incrementing leftpos, at one stage its value will be greater than the size of array arr and accessing the array element beyond the size of the array is undefined behavior which includes program may give segmentation fault. It should be:
while(rightpos<=last)
newarr[newpos++]=arr[rightpos++];

trying to print a array of structs in C

I was asked to build a function that's receive a static two dimensional array with a lot of zeroes and turn it to an array of structs. each struct contains the value which is not zero and the index of the column.
Now I have built it but the problem is with the print function.
1) When I try to print twice it only prints one time and the second time list becomes NULL. Why does this occur?
print(list);
print(list);
2) Why can't I print like I did in the main function?
printf("this is just a print |%d||%d| ", list[0]->next->next->next->data, list[0]->col);
Why I don't have access to it, the program crashes...
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//#include <vld.h>
#include <string.h>
#include <ctype.h>
#define C 5
#define N 4
typedef struct Node {
int data;
int col;
struct Node *next;
} node;
node **fun(int arr[N][C]) {
int i, j, k;
node **list;
node *temp;
list = (node**)calloc(N, sizeof(node *));
for (i = 0; i < N; i++) {
list[i] = NULL;
for (j = C - 1; j >= 0; j--)
if (arr[i][j] != 0) {
temp = (node*)malloc(sizeof(node));
temp->data = arr[i][j];
temp->col = j;
temp->next = list[i];
list[i] = temp;
}
}
return list;
}
void print(node **head) {
int i;
node **temp = head;
for (i = 0; i < N; i++) {
while (temp[i]) {
printf("|%d||%d| ", temp[i]->data, temp[i]->col);
temp[i] = temp[i]->next;
}
printf("\n\n");
}
}
void main() {
int arr[N][C] = { {0,0,4,0,7}, {3,0,0,0,0}, {9,1,0,6,0} , {0,0,0,0,0} };
node **list;
list = fun(arr);
print(list); ///////////
print(list); ///////////////
printf("this is just a print |%d||%d| ", list[0]->next->next->next->data, list[0]->col);
}
As was mentioned in the comments, you are destroying your list of pointer in the process of printing them:
while(temp[i])
{ printf("|%d||%d| ",temp[i]->data,temp[i]->col);
temp[i]=temp[i]->next; // <---- here
}
Each temp[i] is the same as head[i], so you modify the original list as you do this. The while loop exits when this value is NULL, so the end result is that all array elements are NULL.
You need to assign this value to a temporary so you can walk the list without changing it:
node *temp2 = temp[i];
while(temp2)
{ printf("|%d||%d| ",temp2->data,temp2->col);
temp2=temp2->next;
}
Your print function modifies the array: it uses the array elements to iterate through the lists, and leaves them with a NULL value.
Here is a corrected version:
void print(node **head) {
int i;
for (i = 0; i < N; i++) {
node *temp;
for (temp = head[i]; temp; temp = temp->next) {
printf("|%d||%d| ", temp->data, temp->col);
}
printf("\n\n");
}
}

Applying bubble sort on linked list gives wrong output in c

I am trying to sort a linked list using bubble sort.But it gives segmentation problem
My logic to do so is below:
Note: Please note that i have to use only pass by reference every where (no return and global declaration for nodes)
void bubble_sort(node * * List, int size)
{
int i, j, temp;
node * first;
node * second;
node * final;
final=*List
for (i = 0; i < size - 1; i++)
{
first =final;
second = first -> link;
for (j = 0; j < size; j++)
{
if (first -> data < second -> data)
{
temp = first -> data;
first -> data = second -> data;
second -> data = temp;
}
first = first -> link;
}
} * List = first;
}
It's function call is :
bubble_sort(&start,val);
Could any one please help me in correcting the logic ?
EDIT: My full code:
#include <stdio.h>
//#include <conio.h>
#include <malloc.h>
/* structure containing a data part and link part */
struct node
{
int data;
struct node * link;
};
typedef struct node node;
node * start, * visit, * newnode;
//start=NULL
///////////////////////////////// Function declaration ///////////////////
void append(node * * q, int num);
void displaylist(node * start);
void bubble_sort(node * * List, int val);
//////////////////////////////////////////////////////////////////////////////////////////
void append(node * * q, int num)
{
node * temp, * temp2;
temp = * q;
//temp= (node* )malloc(sizeof (node));
if (temp == NULL) /* if the list is empty, create first node */
{
temp = (node * ) malloc(sizeof(struct node)); * q = temp;
} else
{
temp2 = * q;
while (temp2 -> link != NULL)
{
temp2 = temp2 -> link;
}
temp = (node * ) malloc(sizeof(struct node));
temp2 -> link = temp;
}
temp -> data = num;
temp -> link = NULL;
}
///////////////////////////////////////////////////////////////////////
void displaylist(node * start)
{
visit = start;
/* traverse the entire linked list */
while (visit != NULL)
{
printf("%d ", visit -> data);
visit = visit -> link;
}
}
/////////////////////////////////////////////////////////////////////////////////
/*
void bubble_sort(node **List,int size)
{
int i,j,temp;
node*first;
node*second;
node*final;
final=*List;
for(i=0;i<size-1;i++)
{
first=final;
second=first->link;
for(j=1;j<size;j++)
{
if( first->data<second->data)
{
temp=first->data;
first->data=second->data;
second->data=temp;
}
first=first->link;
}
}
*List=first;
} */
//////////////////////////////////////////////////////////////////////////////////////
void bubble_sort(node * * List, int size)
{
int i, j, temp;
node * first;
node * second;
node * final;
for (i = 0; i < size; i++)
{
first = * List;
for (j = 0; j < size - 1; j++)
{
if (first -> data < first -> link -> data)
{
temp = first -> data;
first -> data = first -> link -> data;
first -> link -> data = temp;
}
first = first -> link;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////
main()
{
start = NULL;
int val, n, size;
char ch;
struct node * new;
new = NULL;
printf("\nEnter the size desired size of Linked list: \n");
scanf("%d", & size);
for (ch = 0; ch < size; ch++)
{
printf("\nEnter a value: ");
scanf("%d", & val);
append( & new, val);
}
start = new;
displaylist(start);
printf("\nApplying Bubble sort on Linked list: \n");
bubble_sort( & start, val);
displaylist(start);
printf("\n");
}
Assumed Val is number of nodes in list, you are actually not sorting a linked list but instead swapping the values from one node to another in order to sort it.
bubble_sort( &start, size); change this as well should fix it(pass size not val)
try this.
void bubble_sort(node **List, int val)
{
int i,j,temp;
node *first;
node *second;
node *final;
for(i = 0; i < val; i++)
{
first = *list
for(j = 0; j < val-1; j++)
{
if(first->data < first->link->data)
{
temp = first->data;
first->data = first->link->data;
first->link->data = temp;
}
first = first->link;
}
}
}
I believe you are getting a segmentation fault because you're trying to access a Null pointer as a node, in the inner for-loop.
for (j = 0; j < val; j++)
this should be:
for (j = 0; j < val - 1; j++)
Because in your solution, when j = val-1, it will still try and access first->link->data, however, first->link is Null.

Segmentation fault upon insertion into binary search tree

I wrote the following code to insert into binary search tree which can have duplicate entries but i get segmentation fault for larger inputs like greater than 30 ....plz help!! The duplicate entries are stored in the right branch of the node
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
typedef struct vertex{
int num;
struct vertex* r;
struct vertex* l;
} node;
void insert(node* T,int x)
{
if(x < T->num)
{
if(T->l == NULL)
{
T->l = (node*)malloc(sizeof(node));
T->l->num = x;
printf("%4d ",x);
return;
}
else
{
insert(T->l,x);
}
}
else if(x >= T->num)
{
if(x == T -> num)
if(T->r == NULL)
{
T->r = (node*)malloc(sizeof(node));
T->r->num = x;
printf("%4d ",x);
return;
}
else
insert(T->r,x);
}
}
main()
{
srand((unsigned int)time(NULL));
int i,n,m,x;
node* T;
printf("n = ");
scanf("%d",&n);
printf("\nm = ",&m);
scanf("%d",&m);
printf("\n\n\n+++ Inserting %d random integers between 1 and %d\n",n,m);
x = 1 + rand() % m;
T = (node*)malloc(sizeof(node));
T->num = x;
printf("%4d (1)",x);
for(i=1;i<n;i++)
{
x = 1+rand() % m;
insert(T,x);
if(i%8 == 7)
printf("\n");
}
printf("\n\n");
}
malloc() does not initialize memory, so set other member to NULL after allocation or use calloc(). Without this you will be accessing random memory when you do T->l or T->r.
T = malloc(sizeof(node));
T->num = x;
T->l = NULL;
T->r = NULL;
or
T = calloc(1, sizeof(node));
T->num = x;
Do this in all places where you use malloc()
malloc(noofbytes) function only allocate noofbytes space only does not initialize with NULL .
This is the problem with your code.
When you allocate memory
T->l = (node*)malloc(sizeof(node));
T->l->num = x;
you allocated memory of size of structure node but it is not initialized . Means
T->l->l and T->l->r is not NULL and have some garbage value.
when you traverse it T->l== NULL or T->r==NULL condition not get satisfied and so it gives segmentation fault.

Resources