Call rotate function in AVL Tree C - c

I have this code to rightRotate a sub tree :
void rightRotate(mynode **parentPtr, mynode *child)
{
// make sure the arguments are valid for a right rotation
assert(parentPtr != NULL && child != NULL && child->left != NULL);
// save the three node addresses involved in the rotation
mynode *F = child;
mynode *D = F->left;
mynode *E = D->right;
// perform the rotation
*parentPtr = D;
D->right = F;
F->left = E;
}
Tree struct is :
typedef struct tree mynode; // differences between nametag and type????
struct tree{ // tree node struct
int value;
int key;
char color;
struct tree *left;
struct tree *right;
};
My question is : How should I call this function ?
Example : I have a tree and I want to right rotate son, since the first argument is a pointer to pointer to node and the second a pointer to node how should I write the call?
//...some code...
//I have two pointers to nodes : parent and son
rightRotate ( ??? , son)// I didn't get the first argument, what I should write?
//some code...
P.S. : This code is from an other post, sorry for this little "spam" but I'm very confused about this simple function and why it works in this way. Can someone explain me a little more?

Related

Deserialize a BST in C

I am trying to construct a BST given a string. It is assumed that my strlen will always be in the power of 2 so that I can have a structure with the ends always leveled, like so:
I am having trouble starting this function. I've written a helper that willd construct a tree up to the final points here:
tree* build(int height)
{
int i;
tree *t = malloc(sizeof(tree));
t.tag = NODE;
t.u = node;
t.u.node->left = build(height - 1);
t.u.node->right = build(height - 1);
if(height == 1)
{
return t;
}
}
I would like to reach the end of each node and append the first two chars and so forth throughout the rest of the tree. I am lost, though.
Here are the structs:
typedef struct tagged_tree tree;
struct node {
tree *left, *right;
};
union tree_union {
struct node node;
char leaf;
};
enum tree_tag {
NODE, LEAF
};
struct tagged_tree {
enum tree_tag tag;
union tree_union u;
};

Save C binary tree root value in variable

Im working on a C library for binary tree, and Im wondering how I could save the value of the root of the tree to be able to display it later in a function.
My tree struct:
struct Node {
int value;
struct Node *left;
struct Node *right;
};
typedef struct Node TNode;
typedef struct Node *binary_tree;
The binary tree root is initialised with the 3 value like this:
caller:
tree = NewBinaryTree(3);
NewBinaryTree method:
binary_tree NewBinaryTree(int value_root) {
binary_tree newRoot = malloc(sizeof(TNode));
if (newRoot) {
newRoot->value = value_root;
newRoot->left = NULL;
newRoot->right = NULL;
}
return newRoot;
}
Basically I would like to be able to do a function that just display the value_root function even after adding elements to the binary tree and be able to still display the value_root value.This might be very basic but im learning C and im not sure.
thank you
In the caller: printf( "%d\n", tree->value )
– user3386109

AVL Tree Deletion using Recursion

Let x = the node to be deleted
How can I reassign the left or right pointer of x's parent to x's left or right sub tree during rotation without a parent pointer in node's struct declaration using recursion in an AVL Tree Implementation coded in C?
My Node's struct declaration:
typedef struct Node{
int key;
struct Node *left;
struct Node *right;
int height;
}node;
Currently, these are my rotation codes:
void rotateRight(node **n){
node *lChild = (*n)->left;
node *subtree = lChild->right;
// Rotate Right
lChild->right = *n;
(*n)->left = subtree;
*n = lChild;
// Update Height
lChild->right->height = max(getHeight(lChild->right->left), getHeight(lChild->right->right)) + 1;
(*n)->height = max(getHeight((*n)->left), getHeight((*n)->right)) + 1;
}
void rotateLeft(node **n){
node *rChild = (*n)->right;
node *subtree = rChild->left;
// Rotate Left
rChild->left = *n;
(*n)->right = subtree;
*n = rChild;
// Update Height
rChild->left->height = max(getHeight(rChild->left->left), getHeight(rChild->left->right)) + 1;
(*n)->height = max(getHeight((*n)->left), getHeight((*n)->right)) + 1;
}
When I execute these rotation codes, I lose some elements that should have not been deleted.
You can't. Either add a pointer to parent to your structure, or write your recursion in a way that passes node and parent on each level, so you can pass the parent as a second parameter to your rotate functions.

Using Pointer to Pointer of Struct while adding nodes in the binary tree

I want to know the reason why do we use, pointer to pointer while inserting nodes in the binary tree.
But, While traversing the binary tree, we just refer the tree by simple pointer to the root node. But why while inserting node?
Can anyone help me in providing the reason or reference link to understand why it is pointer to pointer .
/*This program clears out all the three methods of traversal */
#include<stdio.h>
#include<stdlib.h>
/* Let us basically describe how a particular node looks in the binary tree .... Every node in the tree has three major elements , left child, right child, and and the data. */
struct TreeNode {
int data;
struct TreeNode *leftChild;
struct TreeNode *rightChild;
};
void inorder(struct TreeNode *bt);
void preorder(struct TreeNode *bt);
void postorder(struct TreeNode *bt);
int insert(struct TreeNode **bt,int num);
main()
{
int num,elements;
struct TreeNode *bt;
int i;
printf("Enter number of elements to be inserted in the tree");
scanf("%d",&num);
printf("Enter the elements to be inserted inside the tree");
for(i=0;i<num;i++)
{
scanf("%d",&elements);
insert(&bt,elements);
printf("\n");
}
printf("In Order Traversal \n");
inorder(bt);
printf("Pre Order Traversal \n");
preorder(bt);
printf("Post Order Traversal \n");
postorder(bt);
return 0;
}
int insert(struct TreeNode **bt,int num)
{
if(*bt==NULL)
{
*bt= malloc(sizeof(struct TreeNode));
(*bt)->leftChild=NULL;
(*bt)->data=num;
(*bt)->rightChild=NULL;
return;
}
else{
/* */
if(num < (*bt)->data)
{
insert(&((*bt)->leftChild),num);
}
else
{
insert(&((*bt)->rightChild),num);
}
}
return;
}
void inorder(struct TreeNode *bt){
if(bt!=NULL){
//Process the left node
inorder(bt->leftChild);
/*print the data of the parent node */
//printf(" %d ", bt->data);
/*process the right node */
inorder(bt->rightChild);
}
}
void preorder(struct TreeNode *bt){
if(bt)
{
//Process the parent node first
printf("%d",bt->data);
//Process the left node.
preorder(bt->leftChild);
//Process the right node.
preorder(bt->rightChild);
}
}
void postorder(struct TreeNode *bt){
if(bt)
{
//process the left child
postorder(bt->leftChild);
//process the right child
postorder(bt->rightChild);
//process the parent node
printf("%d",bt->data);
}
}
"I want to know the reason why do we use, pointer to pointer while inserting nodes in the binary tree. But, While traversing the binary tree, we just refer the tree by simple pointer to the root node. But why while inserting node?"
We actually don't even need the code to answer this. If you want to modify (write to) data in an external function in C, you need to have the address of the data. Just like:
main() {
int x = 2;
change_me(x);
printf("%d\n", x); // prints 2
}
void change_me(int x){
x++;
}
has no meaning. You're (in this example) getting a local copy of the vairable, any changes made to the value are only within the local scope. If you want those changes to propagate back to the calling function you need the address:
main() {
int x = 2;
change_me(&x);
printf("%d\n", x); // prints 3
}
void change_me(int* x){
(*x)++;
}
The same applies to pointers. In the example of a linked list, if I want to print the values, I need to traverse the tree and read data. I don't need to change anything so just the pointer will do. However if I want to modify the tree:
struct node{
int val;
sturct node* next;
};
main() {
struct node* head = malloc(sizeof(struct node));
head->val = 3;
insert_a_node_in_front(head);
}
insert_a_node_in_front(node * ptr) {
struct node* temp = ptr;
ptr = malloc(sizeof(struct node));
ptr->val = 5;
ptr->next = temp;
}
Well, guess what? We didn't actually just insert that node because head's value never changed. It's still pointing to the original node with a val==3. The reason is the same as before, we tried to change the value of the local copy of the parameter. If we want those changes to stick it needs the address of the original copy:
insert_a_node_in_front(&head);
}
insert_a_node_in_front(node ** ptr) {
struct node* temp = (*ptr);
(*ptr) = malloc(sizeof(struct node));
(*ptr)->val = 5;
(*ptr)->next = temp;
}
It's because of the first part of insert where it mallocs a new struct treenode. If you only passed in a struct treenode * this would look something like this:
int insert(struct TreeNode *bt,int num)
{
if(bt==NULL)
{
bt= malloc(sizeof(struct TreeNode));
(bt)->leftChild=NULL;
(bt)->data=num;
(bt)->rightChild=NULL;
return;
}
...
}
The problem with that would be that bt is local to insert so the bt in main would be unchanged. So you pass in a pointer to main's bt, which allows insert to change it.
a very good tips on using pointer is given here :
Try this basics : -
http://www.geeksforgeeks.org/how-to-write-functions-that-modify-the-head-pointer-of-a-linked-list/

BST with a recursion and given structures

I have to code some methods for a BST and I have some problems, let me explain.
I have the following structures :
struct node {
struct node *lChild;
struct node *rChild;
int value;
};
and
struct tree {
struct node *root;
};
along with the following functions :
struct tree* constructNewTree()
{
struct tree *T=malloc(sizeof(struct tree));
T->root=NULL;
return T;
}
and
struct node* constructNewNode(int i)
{
struct node *N=malloc(sizeof(struct node));
N->value=i;
N->lChild=NULL;
N->rChild=NULL;
return N;
}
And in my main I must call this (for example) :
int main()
{
struct tree *T;
T=constructNewTree();
insertKey(5,T);
insertKey(2,T);
insertKey(9,T);
return 0;
}
What I have to do is to create the function insertKey(int i, struct tree *T) using the recursion.
I wanted to do something like
void insertKey(int i, struct tree *T)
{
if (T->root==NULL) {
T->root=constructNewNode(i);
return;
}
else {
if (i<=T->root->value) {
T->root->lChild=constructNewNode(i);
else if (i>T->root->value) {
T->root->rChild=constructNewNode(i);
}
}
}
But it doesn't get very far, using the recursion would allow me to call insertKey again but I can't seem to use a node and a tree the same way.
Does anyone know how I could do that without altering the given structures?
Thank you very much.
Your insertKey takes a Tree as its argument. A Tree is only a pointer to the very top.
What I recommend you do is write a insertKey function that takes a Node for its argument. Also in this function, you have to check to see if there is another tree on the left/right child.
Currently you just construct a new node regardless of what is there. This will overwrite any previous insertions.

Resources