Universität Ulm,
SAI,
Übungen zu
Systemnahe Software I
Lösungsbeispiel zu Blatt 7 (Aufgabe 11)
/*
* tree.c - Beispielprogramm fuer binaere Baeume
*
* Synopsis: tree
*
* Erzeugen eines ausgeglichenen binaeren Baums mit N Datensaetzen,
* die in sortierter Folge aus der Standardeingabe gelesen werden,
* wobei N eine fest vorgegebene Zahl darstellt;
*
* Ausgabe der Baumstruktur auf die Standardausgabe;
*
* Bereitstellung von Funktionen zur Ausgabe aller Datensaetze
* in inorder-, preorder- und postorder-Reihenfolge;
*
* Lesen und Einfuegen weiterer Datensaetze aus der Standardeingabe
* bis zum Ende der Eingabe;
*
* Schreiben der Daten in die Standardausgabe.
*
* Martin Hasch, Universitaet Ulm, Januar 1997.
*/
#include <stdio.h>
#include <malloc.h>
#define TREESIZE 5 /* N */
typedef struct tree {
int t_key;
struct tree *t_left, *t_right;
} *Tree;
/*
* Allokation eines neuen Knotens ohne Initialisierung.
* Resultat ist der neue Knoten. Erfolg wird garantiert.
*/
static Tree new_tree(void)
{
Tree result;
result = (Tree) malloc( sizeof(struct tree) );
if ( !result ) {
fprintf(stderr, "out of memory!\n");
exit(2);
}
return result;
}
/*
* Ausgabe eines Datensatzes.
*/
static void print_element(Tree element)
{
printf("%d\n", element->t_key);
}
/*
* Lesen eines Datensatzes. Resultat ist 1 bei Erfolg, sonst 0.
*/
static int read_element(int *key)
{
return scanf("%d", key) == 1;
}
/*
* Einlesen eines Baumes mit (size) Elementen.
* Korrekte Syntax und Reihenfolge wird vorausgesetzt.
*/
void buildTree(Tree *tree, int size)
{
Tree this;
if ( size <= 0 ) {
this = NULL;
} else {
this = new_tree();
buildTree(&this->t_left, size/2);
if ( !read_element(&this->t_key) ) {
fprintf(stderr, "number expected!\n");
exit(1);
}
buildTree(&this->t_right, (size-1)/2);
}
*tree = this;
}
/*
* Ausgabe der Struktur eines Baumes in zweidimensionaler Form.
*/
void printTree(Tree tree, int level)
{
if ( tree != NULL ) {
printTree(tree->t_left, level+1);
printf("%*s%d\n", level*4, "", tree->t_key);
printTree(tree->t_right, level+1);
}
}
/*
* Ausgabe aller Datensaetze eines Baumes in inorder-Reihenfolge.
*/
void inorder(Tree tree)
{
if ( tree != NULL ) {
inorder(tree->t_left);
print_element(tree);
inorder(tree->t_right);
}
}
/*
* Ausgabe aller Datensaetze eines Baumes in preorder-Reihenfolge.
*/
void preorder(Tree tree)
{
if ( tree != NULL ) {
print_element(tree);
preorder(tree->t_left);
preorder(tree->t_right);
}
}
/*
* Ausgabe aller Datensaetze eines Baumes in postorder-Reihenfolge.
*/
void postorder(Tree tree)
{
if ( tree != NULL ) {
postorder(tree->t_left);
postorder(tree->t_right);
print_element(tree);
}
}
/*
* Suche eines Datensatzes mit Schluessel (key) in einem Baum;
* Einfuegen, falls noch nicht vorhanden.
* Resultat ist ein Zeiger auf den Datensatz.
*/
Tree * insert(Tree *tree, int key)
{
while ( *tree != NULL ) {
if ( key < (*tree)->t_key )
tree = &(*tree)->t_left;
else if ( key > (*tree)->t_key )
tree = &(*tree)->t_right;
else
return tree;
}
*tree = new_tree();
(*tree)->t_key = key;
(*tree)->t_left = (*tree)->t_right = NULL;
return tree;
}
/*
* Testprogramm.
*/
int main(void)
{
static Tree data;
int key;
buildTree(&data, TREESIZE);
printTree(data, 0);
while ( read_element(&key) ) {
(void) insert(&data, key);
}
printf("inorder:\n");
inorder(data);
printf("preorder:\n");
preorder(data);
printf("postorder:\n");
postorder(data);
return 0;
}
Zugehöriges Aufgabenblatt /
Nächstes Aufgabenblatt /
Nächstes Lösungsbeispiel /
Alle Aufgaben
Martin Hasch, Januar 1997