Commit c31079ce authored by Paffenholz, Andreas's avatar Paffenholz, Andreas

programs ch 14

parent bb078471
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* AVL-Baum
**************************************/
#include <stdio.h>
#include <stdlib.h>
#include "avl_tree.h"
struct node *newNode(int data) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
if( temp == NULL ) {
fprintf (stderr, "kein Speicher mehr\n");
exit(1);
}
temp->data = data;
temp->height = 0;
temp->left_child = temp->right_child = NULL;
return temp;
}
static int height( struct node * node ) {
if( node == NULL ) {
return -1;
}
return node->height;
}
int balance(struct node *node) {
if (node == NULL) {
return 0;
}
return height(node->left_child) - height(node->right_child);
}
static int max( int l, int r) {
return l > r ? l: r;
}
static void right_rotation( struct node ** root_ptr ) {
struct node* left_child = (*root_ptr)->left_child;
(*root_ptr)->left_child = left_child->right_child;
left_child->right_child = *root_ptr;
(*root_ptr)->height = max( height( (*root_ptr)->left_child ), height( (*root_ptr)->right_child ) ) + 1;
left_child->height = max( height( left_child->left_child ), (*root_ptr)->height ) + 1;
*root_ptr = left_child;
}
static void left_rotation( struct node ** root_ptr ) {
struct node* right_child = (*root_ptr)->right_child;
(*root_ptr)->right_child = right_child->left_child;
right_child->left_child = *root_ptr;
(*root_ptr)->height = max( height( (*root_ptr)->left_child ), height( (*root_ptr)->right_child ) ) + 1;
right_child->height = max( height( right_child->right_child ), (*root_ptr)->height ) + 1;
*root_ptr = right_child;
}
static void right_left_rotation( struct node ** root_ptr ) {
right_rotation( &(*root_ptr)->right_child );
left_rotation( root_ptr );
}
static void left_right_rotation( struct node ** root_ptr ) {
left_rotation( &(*root_ptr)->left_child );
right_rotation( root_ptr );
}
/* Public Functions */
void free_tree(struct node * node ) {
if( node != NULL ) {
free_tree( node->left_child );
free_tree( node->right_child );
free( node );
}
}
void insert(struct node ** node_ptr, int data ) {
if (*node_ptr == NULL) {
struct node* newnode = newNode(data);
*node_ptr = newnode;
return;
}
if( data < (*node_ptr)->data ) {
insert(&(*node_ptr)->left_child, data );
if( balance( *node_ptr ) == 2 ) {
if( data < (*node_ptr)->left_child->data ) {
right_rotation( node_ptr );
} else {
left_right_rotation( node_ptr );
}
}
} else if( data > (*node_ptr)->data ) {
insert(&(*node_ptr)->right_child, data );
if( balance( *node_ptr ) == -2 ) {
if( data > (*node_ptr)->right_child->data ) {
left_rotation( node_ptr );
} else {
right_left_rotation( node_ptr );
}
}
}
(*node_ptr)->height = max( height( (*node_ptr)->left_child ), height( (*node_ptr)->right_child ) ) + 1;
}
void delete(struct node** node_ptr, int data) {
if (*node_ptr == NULL) {
return;
}
if ( data < (*node_ptr)->data )
delete(&(*node_ptr)->left_child, data);
else if( data > (*node_ptr)->data )
delete(&(*node_ptr)->right_child, data);
else {
if( ((*node_ptr)->left_child == NULL) || ((*node_ptr)->right_child == NULL) ) {
struct node *temp = (*node_ptr)->left_child ? (*node_ptr)->left_child : (*node_ptr)->right_child;
if (temp == NULL) {
temp = (*node_ptr);
(*node_ptr) = NULL;
} else {
**node_ptr = *temp;
}
free(temp);
} else {
int val = find_min((*node_ptr)->right_child);
(*node_ptr)->data = val;
delete(&(*node_ptr)->right_child, val);
}
}
if ((*node_ptr) == NULL)
return;
(*node_ptr)->height = 1 + max(height((*node_ptr)->left_child), height((*node_ptr)->right_child));
int b = balance(*node_ptr);
if (b == 2 ) {
if ( balance((*node_ptr)->left_child) >= 0) {
right_rotation(node_ptr);
} else {
left_right_rotation(node_ptr);
}
return;
}
if (b == -2 ) {
if ( balance((*node_ptr)->right_child) <= 0) {
left_rotation(node_ptr);
} else {
right_left_rotation(node_ptr);
}
return;
}
}
struct node* find(struct node* node, int data) {
if (node == NULL) {
return NULL;
}
if ( node->data > data ) {
return find(node->left_child, data);
} else if ( node->data < data ) {
return find(node->right_child, data);
}
return node;
}
int find_min(struct node* node) {
if ( node == NULL ) {
return -1;
}
while (node->left_child != NULL)
node = node->left_child;
return node->data;
}
\ No newline at end of file
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* AVL-Baum, Header
**************************************/
#ifndef AVL_TREE_IMPL_H
#define AVL_TREE_IMPL_H
struct node {
struct node * left_child;
struct node * right_child;
int data;
int height;
};
void free_tree (struct node*);
void insert (struct node **, int);
void delete (struct node **, int);
struct node * find (struct node *, int);
int find_min(struct node *);
#endif
\ No newline at end of file
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* AVL-Baum, Testprogramm
*
* Uebersetzen mit
* gcc avl_tree_main.c avl_tree.c avl_tree_print.c -o avl
* Aufruf mit
* ./avl
**************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "avl_tree.h"
#include "avl_tree_print.h"
#define N_INS 20
char get_action() {
char action;
printf("(e)infuegen/(l)oeschen/(s)uchen/(m)inimum/(a)usgeben/als (b)aum ausgeben/(z)urücksetzen/(f)ertig: ");
scanf(" %c",&action);
return action;
}
int main() {
struct node * root = NULL;
srand(time(NULL));
for( int i = 0; i < N_INS; i++ ) {
int value = rand()%100;
insert(&root, value);
}
print_tree(root);
char action;
int cont = 1;
int value = 0;
struct node * node;
while ( cont ) {
action = get_action();
switch(action) {
case 'b' :
print_tree(root);
break;
case 'e' :
printf("Eingabe: ");
scanf("%i",&value);
insert(&root, value);
break;
case 'f' :
cont = 0;
break;
case 'l' :
printf("Eingabe: ");
scanf("%i",&value);
delete(&root, value);
break;
case 'm' :
value = find_min(root);
if ( value != -1 ) {
printf("kleinster Eintrag ist %d\n",node->data);
}
break;
case 's' :
printf("Eingabe: ");
scanf("%i",&value);
node = find(root,value);
if ( node != NULL ) {
printf("%d ist im Baum\n",value);
} else {
printf("%d ist nicht im Baum\n",value);
}
break;
case 'z' :
free_tree(root);
root = NULL;
break;
default :
print_sorted(root);
}
}
free_tree(root);
return 0;
}
\ No newline at end of file
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* AVL-Baum, Ausgabe
**************************************/
#include <stdio.h>
#include <stdlib.h>
#include "avl_tree_print.h"
void print_line_segment(struct segment * segment) {
if ( segment == NULL )
return;
print_line_segment(segment->previous);
printf("%s", segment->seg);
}
void print_tree_rec(struct node *node, struct segment * previous, int is_left) {
if (node == NULL) {
return;
}
struct segment * segment = malloc(sizeof(struct segment));
segment->previous = previous;
char * previous_seg = " ";
segment->seg = " ";
print_tree_rec(node->left_child, segment, 1);
if ( previous == NULL ) {
segment->seg = "---";
} else if (is_left) {
segment->seg = "/--";
previous_seg = " |";
} else {
segment->seg = "\\--";
previous->seg = previous_seg;
}
print_line_segment(segment);
printf("%d/%d\n", node->data, node->height);
if ( previous != NULL ) {
previous->seg = previous_seg;
}
segment->seg = " |";
print_tree_rec(node->right_child, segment, 0);
if ( previous == NULL ) {
printf("\n");
}
}
void print_inorder(struct node *node) {
if (node != NULL) {
print_inorder(node->left_child);
printf("%d ", node->data);
print_inorder(node->right_child);
}
}
//public
void print_tree(struct node *node) {
print_tree_rec(node,NULL,0);
}
//public
void print_sorted(struct node *node) {
printf("Der Baum in aufsteigender Reihenfolge:\n");
print_inorder(node);
printf("\n");
}
\ No newline at end of file
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* AVL-Baum, Ausgabe, Header
**************************************/
#ifndef AVL_TREE_PRINT
#define AVL_TREE_PRINT
#include "avl_tree.h"
struct segment {
struct segment *previous;
char * seg;
};
void print_sorted(struct node *);
void print_tree(struct node *);
#endif
\ No newline at end of file
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* Binaerer Baum
**************************************/
#include<stdio.h>
#include<stdlib.h>
#include "binary_tree.h"
void free_bst(struct node* node) {
if( node != NULL ) {
free_bst( node->left_child );
free_bst( node->right_child );
free( node );
}
}
struct node *newNode(int data) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
if( temp == NULL ) {
fprintf (stderr, "kein Speicher mehr\n");
exit(1);
}
temp->data = data;
temp->left_child = temp->right_child = NULL;
return temp;
}
void insert(struct node** node_ptr, int data) {
if (*node_ptr == NULL) {
struct node* newnode = newNode(data);
*node_ptr = newnode;
return;
}
if ((*node_ptr)->data >= data )
insert(&(*node_ptr)->left_child, data);
else if ((*node_ptr)->data < data )
insert(&(*node_ptr)->right_child, data);
}
void delete(struct node** node_ptr, int data) {
if (*node_ptr == NULL)
return;
struct node * node = *node_ptr;
if (data < node->data)
delete(&node->left_child, data);
else if (data > node->data)
delete(&node->right_child, data);
else {
if (node->left_child == NULL) {
struct node *temp = node->right_child;
free(node);
*node_ptr = temp;
return;
} else if (node->right_child == NULL) {
struct node *temp = node->left_child;
free(node);
*node_ptr = temp;
return;
}
struct node* temp = find_min(node->right_child);
node->data = temp->data;
delete(&node->right_child, temp->data);
}
return;
}
int find_min(struct node* node) {
if ( node == NULL ) {
return -1;
}
while (node->left_child != NULL)
node = node->left_child;
return node->data;
}
struct node* find(struct node* node, int data) {
if (node == NULL) {
return NULL;
}
if ( node->data > data ) {
return find(node->left_child, data);
} else if ( node->data < data ) {
return find(node->right_child, data);
}
return node;
}
void print_binary_tree_inorder(struct node* node) {
if (node != NULL) {
print_binary_tree_inorder(node->left_child);
printf("%d ", node->data);
print_binary_tree_inorder(node->right_child);
}
}
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* Binaerer Baum, Header
**************************************/
#ifndef BINARY_TREE_H
#define BINARY_TREE_H
struct node {
struct node * left_child;
struct node * right_child;
int data;
};
void free_bst(struct node*);
void insert(struct node**, int);
void delete(struct node**, int);
int find_min(struct node*);
struct node* find (struct node*, int);
void print_binary_tree_inorder(struct node*);
#endif
\ No newline at end of file
/*************************************
* Beispielprogramm zur Vorlesung
* Einfuehrung in die Programmierung I
* Andreas Paffenholz
* TU Darmstadt, Wintersemester 2020/21
* (c) 2020-
*
* Binaerer Baum, Testprogramm
*
* Uebersetzen mit
* gcc binary_tree_main.c binary_tree.c -o binary_tree
* Aufruf mit
* ./binary_tree 10 5 15 13 12 19 23 3 4 1 2
**************************************/
#include <stdio.h>
#include <stdlib.h>
#include "binary_tree.h"
int main(int argc, char** argv) {
struct node * root = NULL;
printf("-- Alle Elemente einfuegen --\n");
for ( int i = 1; i < argc; ++i ) {
insert(&root,atoi(argv[i]));
}
printf("Liste in aufsteigender Reihenfolge: \n");
print_binary_tree_inorder(root);
printf("\n");
printf("\n-- Jedes zweite Element wieder loeschen --\n");
for ( int i = 1; i < argc; i += 2 ) {
delete(&root,atoi(argv[i]));
}
printf("Liste in aufsteigender Reihenfolge: \n");
print_binary_tree_inorder(root);
printf("\n");
return 0;
}
\ No newline at end of file