Problems with creating a tree in C - c

I am trying to create a tree in C (I know how to make one in java, but since I am learning C I thought this would be a great way to really learn pointers), but I am not getting an output when I printf the root's data.
This is my code:
#include<stdio.h>
typedef struct Node
{
struct Node *right;
struct Node *left;
int data;
} Node;
Node* create_node(int data);
Node* create_root(int nodedata)
{
Node* root;
root->data = nodedata;
return root;
}
int main()
{
Node* root = create_root(5);
printf("%d", root->data);
return 0;
}
Is the problem how I am linking the nodes with left and right pointers, or how I am returning the function to a Node pointer?

You should allocate memory before use.
Node* create_root(int nodedata)
{
Node* root = calloc(1, sizeof(Node));
root->data = nodedata;
return root;
}

Related

Deleting head node of a linked list in C where every node knows its headlist

typedef struct node {
int x;
struct node *next;
struct node **head;
} node;
Considering this struct, I've implemented a push function:
node *push(node *nodo, node *top) {
nodo->next = top;
top = nodo;
nodo->head = &top;
return top;
}
so that every node is aware of who is the current head list.
But I have some problems when I have to delete the head of the list:
node *delete(node *top, int x) {
if (top->x == x)
return pop(top);
else
return *other function*;
}
node *pop(node *top) {
node *tmp = top;
top = tmp->next;
free(tmp);
return top;
}
When printing head content, this will give me segmentation fault:
void print(node *top) {
node *tmp = top;
printf("List:\n");
while (tmp != NULL) {
printf("%d\n", (*((tmp)->head))->x);
tmp = tmp->next;
}
printf("\nEnd\n");
}
But I have some problems when I have to delete the head of the list
You have much worse and more pervasive problems.
Here ...
node* push(node* nodo, node* top){
nodo->next=top;
top = nodo;
nodo->head = &top;
return top;
}
You set nodo->head to point to a parameter of the function. The lifetime of that parameter ends when the function returns, at which time the node's head pointer becomes invalid. Undefined behavior results from any subsequent attempt to use the node's head pointer in any way.
I suppose that you have defined node.head as a double pointer so as to be able to change the head node in one place for all nodes. In that case, you need to choose a "one place" that is in fact the same for every node and whose lifetime does not end before that of the overall list does. Having chosen such a location, you would pass it itself to push:
node* push(node* nodo, node** top){
nodo->next = *top;
nodo->head = top;
*top = nodo;
return *top;
}
Of course, all callers would need to be updated appropriately.
However, if you want to have this kind of association between nodes and the list to which they belong, then you should consider creating a separate data structure for the list itself, and giving the nodes a poiunter to that. That would solve several problems for you.
Example:
typedef struct node{
int x;
struct node* next;
struct list* list;
}node;
struct list {
node *head;
// maybe other whole-list information, too, such as the tail node
// or an element count
};
The struct list objects then provide the place for head node pointers to be recorded, and nodes can access their lists' head node via the list.

C Linked List with Sentinel - Getting Access to nodes

I'm struggeling to get this task (Implementing a linked list) done. I tried to build a so called sentinel, which sould make it easier. My question is, how do I get access to the actual elements? I tried to print the roots value (44) but I only get weired values. I assume, that these are adresses of memory (e.g. 6893440).
#include<stdio.h>
struct node {
int val;
struct node* next;
};
struct node** init() {
struct node **l;
l = malloc(sizeof(struct node**));
*l = NULL;
return l;
}
void insert(struct node** l, int val) {
struct node* p;
if(*l == NULL) {
p = malloc(sizeof(struct node));
p->val = val;
p->next = *l;
*l = p;
}
}
void main() {
struct node* list;
list = init();
insert(list, 44); // create a (root)node with value 44
printf("%d", list->val); // e.g. 6893440
}
Thank you very much for your help.
You should declare the list as a double pointer to node.
struct node** list;
Then you can access the value of the first node with
(*list)->val
More info:
In the implementation in data types such as lists in C we often use 2 typedefs to help with the readability of the code and eliminate lots of asterisks and ampersands. These are:
typedef struct node* ListNode;
typedef ListNode* List;
By doing this, you can declare a list simply by:
List list;
Note that the implementation of the list functions also becomes more readable by replacing struct node* and struct node** appropriately.

Connect preorder predecessor with its successor in a binary search tree

Actually in an interview i was asked to write a code through which every node in a binary search tree is having a extra pointer namely "next" we have to connect this pointer of every node to its pre order successor ,can any one suggest me the code as i was not able to do so. the tree nodes has above structure :-
struct node {
int data ;
struct node *left,*right;
struct node *next; //this pointer should point to pre order successor
};
thank you .
Cracked the the solution thanks to you guys ,below is the whole code written in c :-
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left,*right,*next;
};
struct node* getNode(int data)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->left=temp->right=NULL;
temp->data=data;
return temp;
}
void insert(struct node**root,int data)
{
if(!*root)
{
*root=(struct node*)malloc(sizeof(struct node));
(*root)->left=(*root)->right=NULL;
(*root)->data=data;
}
else if(data<(*root)->data)
insert(&((*root)->left),data);
else if(data>(*root)->data)
insert(&((*root)->right),data);
}
struct node* preorderSuccessor(struct node* root,struct node* p)
{
int top,i;
struct node *arr[20];
if(!root || !p)
return NULL;
if(p->left)
return p->left;
if(p->right)
return p->right;
top=-1;
while(root->data!=p->data)
{
arr[++top]=root;
if(p->data<root->data)
root=root->left;
else
root=root->right;
}
for(i=top;i>=0;i--)
{
if(arr[i]->right)
{
if(p!=arr[i]->right)
return arr[i]->right;
}
p=arr[i];
}
return NULL;
}
void connect(struct node* parent,struct node *r)
{
if(r)
{ connect(parent ,r->left);
r->next = preorderSuccessor(parent,r);
connect(parent,r->right);
}
}
int main()
{
struct node* root=NULL,*temp=NULL;
int arr[]={10,11,2,3,9,8,4,5},size,i;
size=sizeof(arr)/sizeof(arr[0]);
for(i=0;i<size;i++)
insert(&root,arr[i]);
connect(root,root);
struct node *ptr = root;
while(ptr){
// -1 is printed if there is no successor
printf("Next of %d is %d \n", ptr->data, ptr->next? ptr->next->data: -1);
ptr = ptr->next;
}
return 0;
}
As Eugene said: So traverse the tree with preorder traversal and connect. To do that, you need to know which node, if any, you visited last.
You can do that with the usual recursive approach by passing a reference to the previous node. This must be the address of a variable that is valid throughout the recursion, because the previous node is not necessarily closer to the root. You could use a global variable, but a variable created in a wrapper function may be better:
void connect_r(struct node *node, struct node **whence)
{
if (node) {
if (*whence) (*whence)->next = node;
*whence = node;
connect_r(node->left, whence);
connect_r(node->right, whence);
}
}
void connect(struct node *head)
{
struct node *p = NULL;
connect_r(head, &p);
if (p) p->next = NULL;
}
The pointer p in connect, whose address is passed to the recursive function connect_r holds the node whose next pointer should be updated next. The update doesn't happen on the first visited node. and the next member of the last visited node must explicitly be set to NULL after the recursion.
Alternatively, you can connect the nodes iteratively by using a stack:
void connect(struct node *head)
{
struct node *p = NULL;
struct node **prev = &p;
struct node *stack[32]; // To do: Prevent overflow
size_t nstack = 0;
if (head) stack[nstack++] = head;
while (nstack) {
struct node *node = stack[--nstack];
*prev = node;
prev = &node->next;
if (node->right) stack[nstack++] = node->right;
if (node->left) stack[nstack++] = node->left;
}
*prev = NULL;
}
The connected next pointers are a snapshot of the current tree. Insertions, deletions and rearrangements of nodes will render the next chain invalid. (But it can be made valid again by calling connect provided that the tree's left and right links are consistent.)

Bus Error 10 on Mac when creating a binary tree in C

I am getting bus error when I'm trying to create a binary tree using structures in C.
Please suggest me a solution to overcome this bus error. I am compiling on Mac OSX.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* left;
struct node* right;
};
struct node* NewNode(int data) {
struct node* inode ;
inode->data = data;
inode->left = NULL;
inode->right = NULL;
printf("%d\n", inode->data);
return(inode);
}
struct node* insert(struct node* node ,int data){
if(node == NULL)
return(NewNode(data));
else{
if(data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);
return(node);
}
}
struct node* build123a() {
struct node* root = newNode(2);
struct node* lChild = newNode(1);
struct node* rChild = newNode(3);
root->left = lChild;
root->right= rChild;
return(root);
}
int main(void) {
build123a();
}
ouput : Bus Error 10
In your newNode function you are defining the structure pointer struct node* inode but not allocating it. And then accessing it to store data, which is incorrect.
inode will have random value (which is taken as address) and when accessing that address, you may get bus error.
You need to allocate memory in your function, like
struct node* NewNode(int data) {
struct node* inode ;
inode = malloc(sizeof(*inode)); //allocate memory
inode->data = data;
inode->left = NULL;
inode->right = NULL;
printf("%d\n", inode->data);
return(inode);
}

pre_order traversal using stack in c

I am not able to figure out why the program is printing only first 3 characters of the tree.
Please help.
#include <stdio.h>
#include <malloc.h>
struct node
{
struct node *left;
char data;
struct node *right;
};
struct node *buildtree(int);
void pre_order(struct node*);
char a[]={'a','b','c','d','e','f','g','\0','\0','h','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
int main()
{
struct node *root;
root = buildtree(0);
printf("pre order traversal:\n");
pre_order(root);
}
struct node *buildtree(int n)
{
struct node *temp = NULL;
if(a[n]!='\0')
{
temp=(struct node*)malloc(sizeof(struct node));
temp->left=buildtree(2*n+1);
temp->data=a[n];
temp->right=(2*n+2);
}
return temp;
}
void pre_order(struct node* root)
{
char stack[30];
struct node* ptr;
int top=1;
stack[1]=NULL;
ptr=root;
while(ptr!=NULL)
{
printf("%c",ptr->data);
if(ptr->right!=NULL)
{
top=top+1;
stack[top]=ptr->right;
}
if(ptr->left!=NULL)
ptr=ptr->left;
else
{
ptr=stack[top];
top=top-1;
}
}
}
I'm surprised that compiled
char stack[30];
should be replaced by
struct node* stack[30];
There might be other problems.
You wrote a nice recursive routine to build the tree, why not write a recursive routine to do a pre-order traversal. It would be much easier to understand.
Simply calling something "stack" won't make it behave as one. When you push something onto a stack, the existing values get pushed down, and the reverse is true for popping.
I'd start with a working stack implementation, preferably with own functions for pushing and popping stuff.

Resources