Could someone direct me to some tutorial on Tree Data Structures using C. I tried googling but most implementations are for C++ or Java.If someone can point me to some online tutorials that are in C it would be great.
Thanks..
Generic tree-traversal methods: http://en.wikipedia.org/wiki/Tree_traversal (see right sidebar for a huge list of algorithms to choose from).
Some tutorials:
http://randu.org/tutorials/c/ads.php
http://www.ehow.com/how_2056293_create-binary-tree-c.html
Here's a bit of tutorial code from a couple of decades ago. In fact, it's been lying around so long, I don't remember where it came from or who wrote it (could have been me, but I'm really not sure). Theoretically it's a bit non-portable, using strdup, which isn't part of the standard library, though most compilers have/supply it.
/* Warning: untested code with no error checking included. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* A tree node. Holds pointers to left and right sub-trees, and some data (a string).
*/
typedef struct node {
struct node *left;
struct node *right;
char *string;
} node;
node *root; /* pointers automatically initialized to NULL */
int insert(const char *string, node *root) {
/* Add a string to the tree. Keeps in order, ignores dupes.
*/
int num = strcmp(root->string, string);
node *temp;
for(;;) {
if ( 0 == num)
/* duplicate string - ignore it. */
return 1;
else if (-1 == num) {
/* create new node, insert as right sub-tree.
*/
if ( NULL == root -> right ) {
temp = malloc(sizeof(node));
temp -> left = NULL;
temp -> right = NULL;
temp -> string = strdup(string);
return 2;
}
else
root = root -> right;
}
else if ( NULL == root ->left ) {
/* create new node, insert as left sub-tree.
*/
temp = malloc(sizeof(node));
temp -> left = NULL;
temp -> right = NULL;
temp -> string = strdup(string);
return 2;
}
else
root = root -> left;
}
}
void print(node *root) {
/* in-order traversal -- first process left sub-tree.
*/
if ( root -> left != NULL )
print(root->left);
/* then process current node.
*/
fputs(root->string, stdout);
/* then process right sub-tree
*/
if ( root->right != NULL )
print(root->right);
}
int main() {
char line[100];
/* Let user enter some data. Enter an EOF (e.g., ctrl-D or F6) when done.
*/
while ( fgets(line, 100, stdin))
insert(line, root);
/* print out the data, in order
*/
print(root);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct binary_node {
struct binary_node *left;
struct binary_node *right; int value;
};
typedef struct binary_node NODE;
int search(NODE *temp, int data)
{
int found = 0;
#if 0
while (temp == NULL) {
if (temp->value == data) {
found = 1;
break;
}
else if (temp->value > data)
temp = temp->left;
else if (temp->value < data)
temp = temp->right;
}
return found;
#endif
if (temp == NULL)
return 0;
else if (temp->value == value)
return 1;
else if (temp->value > data)
return search(temp->left, data);
else if (temp->value < data)
}
NODE *del(NODE *root, int val)
{
if (root = NULL)
return ;
if (val < root->val)
root->left = delete(root->left, val);
else if (val > root->val)
root->right = delete(root->right, val);
else {
if (root->left == NULL && root->right == NULL) {
temp = root;
free(temp);
root = NULL;
}
else if (root->left == NULL) {
temp = root;
root = root->right;
free(temp);
}
else if (root->right == NULL) {
temp = root;
root = root->left;
free(temp);
}
else {
temp = min(root->right);
root->data = temp->data;
root->right = delete(root->right, temp->data);
}
}
return root;
}
NODE *insert_node(NODE *node, int val)
{
if (*node == NULL) {
node = (NODE *) malloc (sizeof(NODE));
node->left = NULL;
node->right = NULL;
node->value = val;
}
if (node->value > val)
node->left = insert_node(node->left, val);
else if (node->value < val)
node->right = insert_node(node->right, val);
else
printf("Discarding the data as it already exists in node\n");
return node;
}
}
int main()
{
NODE *root = NULL;
root = insert_node(root, 50);
insert_node(root, 4);
insert_node(root, 14);
insert_node(root, 44);
insert_node(root, 24);
insert_node(root, 34);
insert_node(root, 74);
insert_node(root, 54);
insert_node(root, 64);
print_order(&root);
search(&root, 34);
del(&root);
return 0;
}
Related
While I know there are cleaner more efficient programs out there for BFS traversal in other languages, in c it gets a bit lengthy
I've found some really lengthy and complicated programs on leetcode, as a beginner those are a little hard to understand, while I understand the basic concept behind it I found a much simpler and cleaner code here sanfoundry
but it doesn't work for some reason? I'd be grateful if someone can help me out with this :)
#include <stdio.h>
#include <stdlib.h>
struct btnode
{
int value;
struct btnode *left, *right;
};
typedef struct btnode node;
/* function declarations */
void insert(node *, node *);
void bfs_traverse(node *);
/*global declarations */
node *root = NULL;
int val, front = 0, rear = -1, i;
int queue[20];
void main()
{
node *new = NULL ;
int num = 1;
printf("Enter the elements of the tree(enter 0 to exit)\n");
while (1)
{
scanf("%d", &num);
if (num == 0)
break;
new = malloc(sizeof(node));
new->left = new->right = NULL;
new->value = num;
if (root == NULL)
root = new;
else
{
insert(new, root);
}
}
printf("elements in a tree in inorder are\n");
queue[++rear] = root->value;
bfs_traverse(root);
for (i = 0;i <= rear;i++)
printf("%d -> ", queue[i]);
printf("%d\n", root->right->right->right->value);
}
/* inserting nodes of a tree */
void insert(node * new , node *root)
{
if (new->value>root->value)
{
if (root->right == NULL)
root->right = new;
else
insert (new, root->right);
}
if (new->value < root->value)
{
if (root->left == NULL)
root->left = new;
else
insert (new, root->left);
}
}
/* displaying elements using BFS traversal */
void bfs_traverse(node *root)
{
val = root->value;
if ((front <= rear)&&(root->value == queue[front]))
{
if (root->left != NULL)
queue[++rear] = root->left->value;
if (root->right != NULL || root->right == NULL)
queue[++rear] = root->right->value;
front++;
}
if (root->left != NULL)
{
bfs_traverse(root->left);
}
if (root->right != NULL)
{
bfs_traverse(root->right);
}
}
I suggest implementing a queue of type btnode *
btnode *queue[20]; // I assume 20 is enought for what you need
...
void bfs_traverse(node *root) {
val = root->val;
if (front <= rear)
{
if (root->left != NULL)
queue[++rear] = root->left;
if (root->right != NULL)
queue[++rear] = root->right;
bfs_traverse(queue[front++]);
}
}
However, I would rather implement it using while. It's much cleaner than a recursive function. I would use recursiveness for DFS
I'm learning binary trees, and I'm trying to delete a node from the binary tree. I get a segmentation fault after infinite recursion in the print in order function. It only does this after the delete function is called. I don't get why this happened. I think it should only happen if the last left pointer in the tree is set to something other than NULL, which would cause the if statement to return to never be triggered. The delete function in this particular case is deleting a node on the right so it shouldn't even touch anything on the left. Help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
struct Node{
//blueprint for node
int data;
struct Node *Left;
struct Node *Right;
};
struct Node *CreateNode(int data){
//utility function to create a new node
struct Node *newNode = malloc(sizeof(struct Node));
newNode->Left = NULL;
newNode->Right = NULL;
newNode->data = data;
return newNode;
}
struct Node *insertNode(struct Node *root, int num){
if(root == NULL){
root = CreateNode(num);
return root;
}
if(root->data >= num){
if(root->Left != NULL){
insertNode(root->Left, num);
}
else{
//if the node on the left of root is equal to NULL
//create a node
root->Left = CreateNode(num);
}
}
else{
if(root->Right != NULL){
insertNode(root->Right, num);
}
else{
//if the node on the right of root is equal to NULL
//create a node
root->Right = CreateNode(num);
}
}
}
void inOrderPrint(struct Node *Head){
//prints nodes in the binary tree in order
if(Head == NULL){
//if the head is null, stop doing recursion
return;
}
//recursivly calls itself and passes in the left node as a parameter
if(Head->Left != NULL){
inOrderPrint(Head->Left);
}
//prints out the data at the current node
printf("%d ", Head->data);
//recusivly calls itself and pases in the right node as a peramater
if(Head->Right != NULL){
inOrderPrint(Head->Right);
}
}
int getHeight(struct Node *Head){
//gets the height of the binary tree
if(Head == 0){
return -1;
}
int left = getHeight(Head->Left)+1;
int right = getHeight(Head->Right) + 1;
if(left > right){
return left;
}
else{
return right;
}
}
int childNum(struct Node *Head){
//returns the number of children the binary search tree node has (directly below it, not counting grand children)
if(Head->Left == NULL && Head->Right == NULL){
//if there is no child
return 0;
}
else if(Head->Left == NULL || Head->Right == NULL){
//if there 1 child
return 1;
}
else{
//if there are two children
return 2;
}
}
int getMax(struct Node *root){
if(root->Right == NULL){
return root->data;
}
else{
return getMax(root->Right);
}
}
struct Node *DeleteNode(struct Node *root, int num){
//function to delete a node from the binary search tree
if(root == NULL){
return root;
}
if(root->data == num){
//if this is the node to be deleted
int numberOfChildren = childNum(root);
if(numberOfChildren == 0){
printf("here??");
free(root);
return NULL;
}
else if(numberOfChildren == 1){
if(root->Left == NULL){
struct Node *temp = root->Right;
free(root);
return temp;
}
else{
struct Node *temp = root->Left;
free(root);
return temp;
}
}
else{
int max = getMax(root->Left);
root->data = max;
DeleteNode(root->Left, max);
return root;
}
}
else if(root->data >= num){
//if this node is greater than or equal to the node to be deleted, recur to the node on the left
root->Left = DeleteNode(root->Left, num);
}
else{
//if this node is less than the node to be deleted, recur to the node on rhe right
root->Right = DeleteNode(root->Right, num);
}
return root;
}
int main()
{
struct Node *root = NULL;
root = insertNode(root, 5);
insertNode(root, 10);
insertNode(root, 3);
insertNode(root, 14);
insertNode(root, 7);
insertNode(root, 16);
inOrderPrint(root);
printf("\nheight: %d", getHeight(root));
DeleteNode(root, 10);
printf("root left: %d", root->Left->data);
printf("\n");
inOrderPrint(root);
//sprintf(result, "%d/%f ...", int);
}
I am new to Data Structures and C. this code work correctly in creating and inserting a node but when i call destroy function its case a Segmentation Fault.It seems to work correctly if i put all the code in the main function instead of other functions.
what cases this bug is :
• destroy
• delete IF deleted the head of the Linked List Only
can anyone please explain to me what is wrong with that?
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int value;
struct node *next;
} node;
node *create_node(int value);
unsigned char insert(node *head, int value);
unsigned char delete_node(node *head, node *old_node);
node *search(node *head, int value);
unsigned char destroy(node *head);
int main(void)
{
node *head = create_node(1);
insert(head, 3);
insert(head, 2);
destroy(head);
for(node *i = head; i != NULL; i = i -> next)
{
printf("%i\n", i -> value);
}
}
// Will create a node and return it if succeeded else it will return NULL
node *create_node(int value)
{
node *new_node = malloc(sizeof(node));
// Check if the node created successfully or not
if (new_node == NULL)
{
return NULL;
}
new_node -> value = value;
new_node -> next = NULL;
return new_node;
}
// Insert the node to a list at the beginning of it, return 0 if succeed else number NOT 0
unsigned char insert(node *head, int value)
{
node *new_node = create_node(value);
// Check if the node created successfully or not
if (new_node == NULL)
{
return 1;
}
// Check if the List is exist or not
if (head == NULL)
{
return 2;
}
new_node -> next = head -> next;
head -> next = new_node;
return 0;
}
// Delete the node, return 0 if succeeded else number NOT 0
unsigned char delete_node(node *head, node *old_node)
{
// Check if the node is exist or not
if (old_node == NULL)
{
return 1;
}
node *back = head;
// If delete the first node ONLY
if (head == old_node)
{
free(old_node);
old_node = NULL;
return 0;
}
while (back -> next != old_node)
{
back = back -> next;
}
back -> next = old_node -> next;
free(old_node);
return 0;
}
// destroy the whole linked list, returns 0 if destroid successfully else number NOT 0
unsigned char destroy(node *head)
{
// Check if the List is exist or not
if (head == NULL)
{
return 1;
}
node *temp = head;
while (temp != NULL)
{
temp = temp -> next;
destroy(temp);
delete_node(head, temp);
}
delete_node(head, head);
return 0;
}
// return Pointer to node if founded it else return NULL
node *search(node *head, int value)
{
while (head != NULL)
{
// If founded it return it's pointer
if (head -> value == value)
{
return head;
}
else
{
head = head -> next;
}
}
return NULL;
}
I don't see exactly where the problem is here, but I do observe that your distroy (sic...) function is unnecessarily complicated. If your purpose is to destroy the entire list, you don't need to call a destroy_node routine. Just do something like this: (pseudocode ...)
while (head != NULL) {
temp = head->next;
free(head);
head = temp;
}
Your destroy_node routine also looks unnecessarily complicated. There are only two cases to consider: deleting the head node, and deleting a node that is not the head node. (pseudocode)
if (node == NULL) return;
if (node == head_node) {
head_node = head_node->next;
free(node);
} else {
temp = head_node;
while ((temp != NULL) {
if (temp->next == node) {
temp->next = temp->next->next; // link it out of the list
free(node);
return;
} else {
temp = temp->next;
}
}
}
your problem is here :
while (temp != NULL)
{
temp = temp -> next;
delete_node(head, temp);
}
your function delete_node(node *head, node *old_node) at the end execute:
free(old_node); // you free temp !
and you dont set old_node to NULL if your free this memory, your can't loop a second time here (because temp deleted):
while (temp != NULL)
{
temp = temp -> next;
delete_node(head, temp);
}
I'm trying to implement a recursive sorting algorithm for linked list structure. C language.
My algorithm is this:
1) find max value in list
2) remove it from the list and insert it at Head node
3) start algorithm again from next node
4) run until you reach end of list
I have something, but it doesn't 'remember' my list. I realize I'm making a mistake somewhere (probably recursive calls), but I can't understand how to fix it.
typedef struct Node{
int data;
struct Node* next;
} Node;
void insert(Node** head, int val)
{
//insert at top
Node* to_insert = (Node*)malloc(sizeof(Node));
to_insert->data = val;
to_insert->next = (*head);
(*head) = to_insert;
}
Node* sort_ll(Node* head)
{
//base case, iterated trough entire list
if(head == NULL)
return NULL;
int max = 0;
Node* tmp = head;
Node* to_move = tmp;
//find maximum value
while(tmp != NULL) {
if(tmp->data > max) {
max = tmp->data;
to_move = tmp;
}
tmp = tmp->next;
}
//if its currently top, leave it there
if(to_move == head) {
return sort_ll(head->next);
}
//find node with max value
tmp = head;
while(tmp->next != to_move) {
tmp = tmp->next;
}
//cut it out from the list
tmp->next = tmp->next->next;
free(to_move);
//insert value at the head of the list
insert(&head, max);
return sort_ll(head->next);
}
int main()
{
Node* list = NULL;
insert(&list, 3);
insert(&list, 6);
insert(&list, 7);
insert(&list, 2);
insert(&list, 1);
insert(&list, 5);
insert(&list, 4);
list = sort_ll(list);
Node* tmp = list;
while(tmp != NULL) {
printf("%d\n", tmp->data);
tmp = tmp->next;
}
return 0;
}
fix like this
Node *sort_ll(Node* head){
if(head == NULL || head->next == NULL)
return head;//There is no need for processing
int max = head->data;
Node *prev = head;
Node *to_move = NULL;
Node *tmp = head->next;
//find maximum value in rest(head->next)
while(tmp != NULL) {
if(tmp->data > max) {
max = tmp->data;
to_move = prev;//save previous node for remove link
}
prev = tmp;
tmp = tmp->next;
}
if(to_move == NULL) {//not find in rest
head->next = sort_ll(head->next);
return head;
}
prev = to_move;
to_move = prev->next;//max node
prev->next = prev->next->next;//max node remove from link
to_move->next = sort_ll(head);
return to_move;
}
typedef struct word {
char *str;
int freq;
struct word *right;
struct word *left;
} Word;
Word *root = NULL; //global
while(pCounter != NULL){
if(root == NULL){
Word *x = (Word *)malloc(sizeof(Word));
x->str = (char*)malloc(strlen(pCounter->str)+1);
//printf("%s", node->str);
strcpy(x->str,pCounter->str);
x->freq = pCounter->freq;
x->left = NULL;
x->right = NULL;
root = x;
}
else {
Insert(pCounter, root);
}
pCounter = pCounter ->pNext;
}
void * Insert(Word *node, Word *root)
{
printf("inserted%s\n", node->str);
if(root==NULL)
{
Word *x = (Word *)malloc(sizeof(Word));
x->str = (char*)malloc(strlen(node->str)+1);
//printf("%s", node->str);
strcpy(x->str,node->str);
x->freq = node->freq;
x->left = NULL;
x->right = NULL;
return x;
//node = root;
}
else if (strcmp(node->str, root->str)==0){
root -> freq = root->freq+1;
}
else if (strcmp(node->str, root->str)<1){
root->left = Insert(node,root->left);
}
else {
root->right = Insert(node, root->right);
}
return node;
}
void ordered(Word *n){
//printf("ordered");
if(n != NULL){
ordered(n->left);
printf("%-30s %5d\n", n->str, n->freq);
ordered(n->right);
}
}
I'm trying to build a binary search tree to process a linked list into an ordered bst. I can get the output of root to show up correctly but not anything else. It spits out some garbage and i'm not sure why. I set up a printf statement and it shows that it is inserting actual strings. Am i doing something wrong? This isn't all the code but I think it's enough so people can understand what i'm doing. Suggestions?
return node; --> return root; As per BLUEPIXY's comment, this was the correct answer.– BLUEPIXY 2 mins ago