This exercise is not really new to me, but it still is quite advance for me. Being a student, I would like to kindly ask for your help regarding this matter.
I need to understand, not just know, how AVL node deletion works. I've been given this C code that I have to complete to demonstrate how AVL insertion and deletion happens. I've done the basics. It's just the balancing and the rotation that got me dizzy.
Here's the main C file:
#include<stdio.h>
#include<stdlib.h>
#include "avl.h"
#define N 10
#define BALANCED 0
#define LEFT_LEANING 1
#define RIGHT_LEANING 2
int main(){
AVL *root=NULL;
int choice=0,x;
while((choice=menu())!=3){
printf("Value: ");
scanf("%i",&x);
switch(choice){
case 1: insert_value(&root,x);
view(root,2);
break;
case 2: delete_value(&root,x);
view(root,2);
}
}
}
here's the avl header file:
#define N 10
#define BALANCED 0
#define LEFT_LEANING 1
#define RIGHT_LEANING 2
//structure for an avl_node
typedef struct node_tag{
int x, height;
struct node_tag *parent;
struct node_tag *left;
struct node_tag *right;
}avl_node;
//print menu and get user choice
int menu(){
int choice;
printf("\n MENU ");
printf("\n[1] - Insert");
printf("\n[2] - Delete");
printf("\n[3] - Exit");
printf("\nYour choice: ");
scanf("%i",&choice);
return choice;
}
//find maximum of 2 numbers
int max(int a,int b){
return(a>b?a:b);
}
//finds the minimum value of the BST
avl_node* minimum(avl_node *rootptr){
if(rootptr!=NULL){
while(rootptr->left!=NULL) rootptr=rootptr->left;
}
return (rootptr);
}
//update height of a given node
void updateheight(avl_node *temp){
if(temp!=NULL)
temp->height = max(temp->left==NULL?-1:temp->left->height,temp->right==NULL?-1:temp->right->height)+1;
}
//left rotate the subtree
void left_rotate(avl_node **rootptr){
}
//right rotate the subtree
void right_rotate(avl_node **rootptr){
}
//determine rotation of node/s
void insert_fixup(avl_node **rootptr, avl_node *temp){
}
//insert value and create node
void insert_value(avl_node **rootptr, int x){
avl_node *temp;
temp = (avl_node *)malloc(sizeof(avl_node));
temp->x = x;
temp->height = 0;
temp->parent = temp->left = temp->right = NULL;
insert_node(rootptr,temp);
insert_fixup(rootptr,temp);
}
void view(avl_node *root, int tabs){
int i;
if(root != NULL){
view(root->right,tabs + 1);
for(i=0;i<tabs;i++) printf("\t");
printf("%2i\n",root->x);
view(root->left,tabs+1);
}
}//view the AVL
void swap(int *a, int *b){
int temp;
temp = *a; *a = *b; *b = temp;
}//swap values
//look for the successor of a node
avl_node* successor(avl_node *rootptr){
if(rootptr==NULL) return (rootptr);
else if(rootptr->right!=NULL) return (minimum(rootptr->right));
while(rootptr->parent!=NULL){
if(rootptr==rootptr->parent->right) rootptr=rootptr->parent;
else break;
}
return (rootptr->parent);
}
//function for searching the location of the node
avl_node* search(avl_node *root,int x){
if(root==NULL || root->x==x) return root;
else{
if(root->x>x) return(search(root->left,x));
else return(search(root->right,x));
}
}
//function for searching the value of the node
int search_node(avl_node *root, int x){
if(root==NULL) return 0;
if(root->x==x) return 1;
else{
if(root->x>x) return(search_node(root->left,x));
else return(search_node(root->right,x));
}
}
//function for deleting a node
void delete_value(avl_node** root,int x){
}
To understand, You should go through the Wiki Page and also try to understand pseudo code to understand node insertion and deletion in AVL tree. Also you can go through Presentation PPT to understand AVL tree. And to find status of your node from tree you can use search() function.
Related
I wanna write a program about linked list that gets a number and if the number was equal to the one of the nodes' data , gives the number of that node .
like the datas in 3 nodes are
123
56
78
and it gets a number like 56 and its equal to the second node's data so the output should be 2.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
node *next;
};
node* cnode();
void find(node *first,int i,int d);
int main()
{
node *first,*last;
int n,i,x,d;
printf(" How many nodes ?\t");
scanf("%d",&x);
for(i=1;i<=x;i++){
last=cnode();
last->next=first;
first=last;
}
printf("\n enter a particular data:\t");
scanf("%d",&d);
printf("\n number of the particular node:\t");
find(first,i,d);
}
void find(node *first,int i,int d){
int count=0;
while (first != NULL)
{
if (first->data == d)
count++;
first = first->next;
}
if(count != 0){
printf("%d",count);
}
if(count == 0){
printf("\n NOT FOUND ! ");
}
}
According to the C Standard the function main without parameters shall be declared like
int main( void )
Secondly this declaration of the structure
struct node{
int data;
node *next;
};
is not a valid C declaration.
You should write
struct node{
int data;
struct node *next;
};
typedef struct node node;
or
typedef struct node{
int data;
struct node *next;
} node;
You have to initialize at least node first with NULL. Otherwise the program will have undefined behavior.
node *first = NULL,*last;
The parameter i is not used within the function find. So it may be removed.
void find(node *first, int d);
The function definition can look at least like
void find( node *first, int d )
{
int count = 0;
while ( first != NULL && first->data != d )
{
first = first->next;
++count;
}
if ( first != NULL )
{
printf("%d",count);
}
else
{
printf("\n NOT FOUND ! ");
}
}
I have been trying to create a program that prints the order in which nodes in a graph are closed during a DFS search. So in the graph 1->2->3 it should print: 3 2 1, somehow the code below would print 3 1 2, in general
for simple graphs like the one above it will print n 1 2 ... n-2 n-1.
If you know what I'm doing wrong please share.
#include <stdio.h>
#include <stdlib.h>
#define UNVISITED 0
#define VISITING 1
#define CLOSED 2
typedef struct node{
int id;
struct node *next;
}Node;
typedef struct graph{
int V,E;
int *visited;
Node ** list;
Node* order;
}Graph;
Graph *makeGraph(){
int v,e,i;
scanf("%d %d",&v ,&e);
Graph* g = (Graph*)malloc(sizeof(Graph));
g->V=v;
g->E=e;
g->order =NULL;
g->list = (Node**)malloc(v*sizeof(Node*));
g->visited = (int*)malloc(v*sizeof(int));
for(i=0;i<v;++i){
g->list[i]=NULL;
g->visited[i]=UNVISITED;
}
return g;
}
void createArcs(Graph *g){
int from,to;
Node *n = (Node*)malloc(sizeof(Node));
for(int i=0;i<g->E;++i){
scanf("%d %d",&from ,&to);
n->id = to;
n->next = g->list[from-1];
g->list[from-1]=n;
}
return;
}
void visitNode(Graph *g, int i){
if(g->visited[i]==CLOSED)
return;
else if(g->list[i]==NULL){
printf("%d\t", i+1);
g->visited[i]=CLOSED;
return;
}
Node* n = g->list[i];
while(n!=NULL){
visitNode(g,n->id-1);
n=n->next;
}
printf("%d\t", i+1);
g->visited[i]=CLOSED;
return;
}
int main()
{
Graph *g = makeGraph();
createArcs(g);
for(int i=0;i<g->V;i++)
visitNode(g,i);
return 0;
}
#include<stdlib.h>
#include<stdio.h>
struct tree{char info;struct tree *left;struct tree *right;};
struct tree *root;
struct tree *stree(struct tree *root,struct tree *r,char info);
void print_tree(struct tree *root,int l);
int main(void)
{
char s[80];
root=NULL;
do {
printf("enter a letter:");
gets(s);
root=stree(root,root, *s);
}
while(*s); // <- ???
print_tree(root,0);
return 0;
}
struct tree *stree(struct tree *root,struct tree *r,char info;{ // <- ???
if(!r) {
r=(struct tree *) malloc(sizeof(struct tree));
if(!r) {
printf("out of memory \n");
exit(0);
}
r->left=NULL;
r->right=NULL;
r->info=info;
if(!root)
return r;
if(info<root->info)
root->left=r;
else
root->right=r;
return r;}if(info<r->info)stree(r,r->left,info);else
stree(r,r->right,info);return root;}
void print_tree(struct tree *r,int l);
{
int i;
if(!r) return ;
print_tree(r->right,l+1);
for(i=0;i<l;++i)
printf(" ");
printf("%c \n",r->info);
print_tree(r->left,l+1);
}
My guess is not the correct output is, because it is not been updated with the return value of stree.
E.g. if(info<r->info)stree(r,r->left,info); <-- It has been discarded return value.
Your code doesn't compile. So, I rewrite code.
#include <stdio.h>
#include <stdlib.h>
struct tree {
char info;
struct tree *left, *right;
};
struct tree *stree(struct tree *root, char info);//no need `struct tree *r`
void print_tree(struct tree *root, int level);
int main(void){
struct tree *root = NULL;//It does not need to be in a global variable
char letter;
for(;;){
printf("enter a letter:");
if(EOF == scanf("%c", &letter) || letter == '\n')//don't use `gets`
break;
scanf("%*[^\n]");//clear upto newline
scanf("%*c");
root = stree(root, letter);
}
print_tree(root, 0);
//deallocate
return 0;
}
struct tree *stree(struct tree *root, char info){
if(!root){
struct tree *r = malloc(sizeof(*r));
if(!r){
fprintf(stderr, "out of memory\n");
exit(EXIT_FAILURE);
}
r->right = r->left = NULL;
r->info = info;
return r;
}
if(info < root->info)
root->left = stree(root->left, info);
else if(info > root->info)
root->right = stree(root->right, info);
else
;//root->right = stree(root->right, info);
return root;
}
void print_tree(struct tree *r, int level){
if(!r) return ;
print_tree(r->right, level + 1);
printf("%*s%c\n", level, "", r->info);
print_tree(r->left, level + 1);
}
Below is my code for the BST :
insert works fine but search doesnt
typedef struct tree_node{
struct tree_node* parent;
struct tree_node* left;
struct tree_node* right;
int x;
}tree_node;
tree_node *strt=NULL;
tree_node *traverse;
tree_node* create(int info){
tree_node *temp=NULL;
temp=(tree_node*)malloc(sizeof(tree_node));
temp->parent=NULL;
temp->left=NULL;
temp->right=NULL;
temp->x=info;
return temp;
}
tree_node* insert(tree_node *root, int a){
/* here i am printing the address of the node which must be same as the root for the first node */
if(root==NULL){
printf("%d ",create(a));
return create(a);
}
else if(a <= root->x)
return insert(root->left,a);
else
return insert(root->right,a);
return root;
}
tree_node* search_ele(tree_node *root,int info){
if(root==NULL || root->x==info)
return root ;
if(info < root->x)
return search_ele(root->left,info);
else
return search_ele(root->right,info);
}
void display_inorder(tree_node *root){
if(root==NULL)
return;
display_inorder(root->left);
printf("%d ",root->x);
display_inorder(root->right);
}
void main(){
int element;
tree_node *search_element;
while(1){
char ch;
int num;
printf("\nWant to enter a node..??\n\n");
scanf(" %c",&ch);
if(ch=='n'||ch=='N')
break;
else{
printf("Enter the number \n");
scanf("%d",&num);
if(strt==NULL)
printf("Tree is empty...entering first node...!!!\n");
strt=insert(strt,num);
printf("%d",strt);
}
}
printf("Enter the element u want to search\n");
scanf("%d ",&element);
if(search_ele(strt,element)==NULL)
printf("no such element\n");
else
printf("element found\n");
display_inorder(strt);
}
The output displays :
Want to enter a node ?
y
Enter the number
6
Tree is empty...entering first node...!!!
5279480 5279504 (why are these different??)
You print the result of calling create, and then call create again for the return value, thus creating a second node.
First the problems with your BST Algorithm: Your node creation algorithm never attaches new nodes to a parent. Create() sets node->parent to NULL and your insert() never updates the parent variable to root. Additionally, you're never setting the new left/right fields of your new node's parent
Change
return create(a)
to
tree_node * new_node = create(a);
new_node->parent=root;
new_node->parent->left/right=new_node; //include some way to distinguish whether you went left or right in the previous recursive call
return new_node
Now for your address question, you call create() twice, which (think procedurally) results in two malloc() calls, and thus two addresses.
Here is my program which creates a link list and also reverses it.
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *list=NULL;
struct node *root=NULL;
static int count=0;
struct node *create_node(int);//function to create node
void travel_list(void);
void create_list(int);
void reverse_list(void);
int main()
{
int i, j, choice;
printf("Enter a number this will be root of tree\n");
scanf("%d", &i);
create_list(i);
printf("Enter 1 to enter more numbers \n 0 to quit\n");
scanf("%d", &choice);
while (choice!=0){
printf("Enter a no for link list\n");
scanf("%d",&i);
// printf("going to create list in while\n");
create_list(i);
travel_list();
printf("Enter 1 to enter more numbers \n 0 to quit\n");
scanf("%d", &choice);
}
printf("reversing list\n");
reverse_list();
travel_list();
}
// end of function main
void create_list (int data)
{
struct node *t1,*t2;
//printf("in function create_list\n");
t1=create_node(data);
t2=list;
if( count!=0)
{
while(t2->next!=NULL)
{
t2=t2->next;
}
t2->next=t1;
count++;
}
else
{
root=t1;
list=t1;
count++;
}
}
struct node *create_node(int data)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data=data;
temp->next=NULL;
// printf("create node temp->data=%d\n",temp->data);
// printf("the adress of node created %p\n",temp);
return temp;
}
void travel_list(void )
{
struct node *t1;
t1=list;
printf("in travel list\n");
while(t1!=NULL)
{
printf("%d-->",t1->data);
t1=t1->next;
}
printf("\n");
}
void reverse_list(void)
{
struct node *t1,*t2,*t3;
t1=list;
t2=list->next;
t3=list->next->next;
int reverse=0;
if(reverse==0)
{
t1->next=NULL;
t2->next=t1;
t1=t2;
t2=t3;
t3=t3->next;
reverse++;
}
while(t3!=NULL)
{
t2->next=t1;
t1=t2;
t2=t3;
list=t1;
travel_list();
t3=t3->next;
}
t2->next=t1;
list=t2;
}
Above is a fully working code.
I want to know if there can be further enhancement to the above code?
Make your indentation and whitespace usage consistent
Use meaningful identifiers rather than t1, t2 and t3
Make the data member a generic type, for example void * rather than int.
Don't use global variables, pass struct node * pointers to your functions.