SUCHE MIT Google
Web virtualuniversity.ch
HOME DIDAKTIK ECDL ELEKTRONIK GUIDES HR MANAGEMENT MATHEMATIK SOFTWARE TELEKOM
DIENSTE
Anmeldung
Newsletter abonnieren
Sag's einem Freund!
VirtualUniversity als Startseite
Zu den Favoriten hinzufügen
Feedback Formular
e-Learning für Lehrer
Spenden
Autoren login
KURSE SUCHEN
Kurse veröffentlichen

Suche nach Datum:

Suche mit Schlüsselwort:

Suche nach Land:

Suche nach Kategorie:
PARTNER
ausbildung24.ch - Ausbildungsportal, Seminare, Kursen... 

 
HTMLopen.de - Alles was ein Webmaster braucht

 
PCopen.de - PC LAN Netze und Netzwerke - alles was ein IT Profi und Systemtechnicker braucht

SOFTWARE
  • Falls ein Baum keinen Knoten besitzt, wird er leerer Baum genannt.
  • Die maximale Anzahl der direkten Nachfolger, die ein Knoten hat, heiß Grad des Baumes.

    Ein Baum vom Grad 2 ist der binäre Baum. Er stellt einen wichtigen Sonderfall dar. Gegenüber dem allgemeinen Baum zeichnet er sich folgendermaßen aus:

    • Jedes Element außer dem Anfangselement hat genau einen direkten Vorgänger.
    • Jedes Element hat null bis zwei direkte Nachfolger, die als linker bzw. rechter Nachfolger unterschieden werden.
    • Der Binärbaum besteht also aus einer Wurzel und zwei Teilbämen, wobei ein Baum und damit auch ein Teilbaum leer sein kann.
    • Eine Sonderform ist der vollständige Binärbaum, bei dem jeder Knoten außer den Blättern zwei nicht leere Teilbäume besitzt und jeder Pfad die gleiche Länge hat.
    Offensichtlich kann man in einem binären Baum der Tiefe n höchstens 2n-1 Knoten unterbringen. Bei einem unvollständigen Baum sind es entsprechend weniger. Im ungünstigsten Fall lassen sich nur n Elemente unterbringen, genau dann, wenn jeder Knoten nur einen Nachfolger besitzt. In diesem Fall degeneriert der Baum zu einer linearen Liste.

    Die Baumstruktur ist rekursiver Natur, da die Nachfolger eines Knotens jeweils wieder als Wurzeln von Bäumen aufgefasst werden können. Diese Baum-Teilbaum-Beziehung lässt sich rekursiv wie folgt definieren:

    Ein Binärbaum ist entweder leer oder er besteht aus einer Wurzel, die über bis zu zwei Kanten mit disjunkten nicht-leeren Binärbäumen verbunden ist.

    Wenn die Knoteninhalte untereinander keine Ordnung besitzen ist der Baum ungeordnet. Bei geordneten Bäumen ist eine vollständige Ordnungsrelation zwischen den Knoten Voraussetzung. Sie wird oft über einen Schlüssel realisiert. Beispiele für Ordnungsschlüssel sind:

    • Enthalten die Knoten nur natürliche Zahlen, so ist die numerische Ordnung eine derartige Relation.
    • Falls die Knoten Zeichenketten enthalten, so ist die lexikographische Ordnung geeignet.
    Lege nun "<" eine vollständige Ordnungsrelation zwischen den Knoten eines Binärbaums fest, dann ist jeder Knoten des Baums kleiner als alle Knoten seines rechten Teilbaums und zugleich größer oder gleich als alle Knoten seines linken Teilbaums.

    Offensichtlich gilt für jeden Knoten, daß ein kleinerer Nochfolgeknoten links und ein größerer rechts unterhalb anzuordnen ist. Nach der verwendeten Ordnungsrelation ist im Fall der Gleichheit ein Nachfolgeknoten ebenfalls links unterhalb anzuordnen.

    Der Suchbaum

    Der geordnete Baum erlaubt eine schnelle Suche von Informationen, ähnlich wie das binäre Suchverfahren in linearen Strukturen. Der geordnete Baum heißt deshalb auch Suchbaum. Dazu ein Beispiel. Gegeben sei folgende lineare Liste:

    Der direkte Zugriff auf die Elemente der Liste sei möglich. Bei der binären Suche wird auf das mittlere Element zugegriffen. Das Anfangselement ist somit nicht mehr A sondern E, das die Liste in zwei Teile teilt:

    Ist E nicht das gesuchte Element, wird in der linken oder rechten Teilliste weitergesucht.

    Teilt man die Liste solange nach diesem Verfahren, bis diese nur noch aus je einem Element bestehen, so liegt ein geordneter Baum in der bekannten Darstellung vor.

    Dieser Baum ist so geordnet, dass alle Elemente im rechten Teilbaum einen lexikalisch größeren Wert besitzen als die Wurzel, und alle Elemente im linken Teilbaum einen kleineren. Dies gilt auch für alle Teilbäume. Einen derart georneten Baum bezeichnet man als binären Suchbaum. Damit wurde die linear verkettete Struktur, auf der im Prinzip nur sequentiell gesucht werden kann, durch Umorganisation in eine binäre Baumstruktur überführt, auf der der Suchvorgang aufgrund der Ordnungsrelation binär verläuft.

    Auch bei der Datenstruktur Baum besteht die Notwendigkeit, Elementinhalte dauerhaft zu speichern und bei Bedarf zu laden. Dies führt zu dem grundsätzlichen Problem, die binär verzweigte Struktur so in eine lineare Struktur zu überführen, dass die Daten so als Datei gespeichert werden können, dass später daraus der ursprüngliche Binärbaum wieder rekonstruiert werden kann. Gegeben sei folgender Binärbaum:

    • Inorder Traversierung
      Die Inorder-Traversierung hat stets die Reihenfolge linker Teilbaum - Wurzel - rechter Teilbaum. Die Wurzel steht in der Mitte. Der Baumdurchlauf nach dem Inorder-Algorithmus hat die besondere Eigenschaft, die nach einem bestimmten Kriterium in den Baum eingefügten Informationen der Knoten in ihrer sortierten Reihenfolge auszugeben.

      2 4 5 7 13 14 16 19 20 22 24 25 26 29 31

                                             inorder (baumtyp *baum)
                                               {
                                               if (baum != NULL)
                                                 {
                                                 inorder (linker_teilbaum);
                                                 verarbeite Wurzelinformation von baum;
                                                 inorder (rechter_teilbaum);
                                                 }
                                               }
                                             
      Anwendungsbeispiel:
      Dies ist die typische Traversierungs-Strategie, um eine vollständig sortierte Liste aus einem Suchbaum zu bekommen: Besuche den linken Teilbaum (in dem alle Elemente kleiner als das Wurzelelement sind), dann die Wurzel, dann den rechten Teilbaum (in dem alle Elemente größer als die Wurzel sind).

    • Postorder Traversierung
      Ändert man den Traversierungsalgorithmus dahingehend ab, dass der Baum in der Reihenfolge linker Teilbaum - rechter Teilbaum - Wurzel durchlaufen wird, spricht man von Postorder-Traversierung.

      2 5 4 13 16 14 7 20 24 22 26 31 29 25 19

      Dieses Ergebnis erzielt man, wenn man von der Wurzel ausgehend links herum alle Knoten längs der Kanten besucht und jedesmal, wenn man rechts neben einem Knoten vorbeikommt, den Knoteninhalt aufschreibt.

                                             postorder (baumtyp *baum)
                                               {
                                               if (baum nicht leer) 
                                                 {
                                                 postorder (linker_teilbaum);
                                                 postorder (rechter_teilbaum);
                                                 verarbeite Wurzelinformation von baum;
                                                 }
                                               }
                                             
      Anwendungsbeispiel:
      Bei einem Taschenrechner oder anderen einfachen Automaten müssen zunächst intern die Argumente einer Rechenoperation in Register geladen werden. Danach wird die verknüpfende Operation aufgerufen (umgekehrt polnische Notation). POST-Order liefert dazu die passende Besuchs-Reihenfolge: (Argument1, Argument2) Operation.

    • Preorder Traversierung
      Eine dritte Möglichkeit der Traversierung besteht in der Reihenfolge Wurzel - linker Teilbaum - rechter Teilbaum:

      19 7 4 2 5 14 13 16 25 22 20 24 29 26 31

      Dieses Ergebnis erzielt man, wenn man von der Wurzel ausgehend links herum alle Knoten längs der Kanten besucht und jedesmal, wenn man links neben einem Knoten vorbeikommt, den Knoteninhalt aufschreibt.

                                             preorder (baumtyp *baum)
                                               {
                                               if (baum nicht leer) 
                                                 {
                                                 verarbeite Wurzelinformation von baum;
                                                 preorder (linker_teilbaum);
                                                 preorder (rechter_teilbaum);
                                                 }
                                               }
                                             
      Anwendungsbeispiel:
      Im Zusammenhang mit Funktionen kann in der Wurzel der Funktionsaufruf, in den Teilbäumen die Argumente stehen. PRE-Order ergibt dann die "gewohnte" Schreibweise Funktion (Argument1, Argument2)

    Beispielimplementierung: Einfügen in einen Baum und Ausgabe des Baums:

                                           #include <stdio.h>
                                           #include <stdlib.h>
                                           #include <string.h>
                                           
                                           #define MAXLEN 80
                                           
                                           struct tnode              /* Binaerbaum */
                                             {
                                             char word[MAXLEN];      /* Text */
                                             int count;              /* Zaehler */
                                             struct tnode *left;     /* linker Nachfolger */
                                             struct tnode *right;    /* rechter Nachfolger */
                                             };
                                           
                                           struct tnode *talloc(void);
                                             /* Platz fuer einen tnode besorgen */
                                           
                                           struct tnode *insert_tree(struct tnode *p,char *w);
                                             /* w bei oder nach p einfuegen */
                                           
                                           void treeprint(struct tnode *p);
                                             /* Baum p rekursiv ausgeben */
                                           
                                           
                                           int main(void)  
                                             {
                                             struct tnode *root;
                                             char word[MAXLEN];
                                           
                                             root = NULL;
                                             while ((gets(word)) != NULL)  /* Baum einlesen */
                                               root = insert_tree(root,word);
                                           
                                             printf("\n");
                                             treeprint(root);              /* Baum ausgeben */
                                           
                                             return(0);  
                                             }
                                           
                                           
                                           struct tnode *talloc(void)
                                             /* Platz fuer einen tnode besorgen */
                                             {
                                             return((struct tnode *) malloc(sizeof(struct tnode)));
                                             }
                                           
                                           
                                           struct tnode *insert_tree(struct tnode *p,char *w)
                                             /* w bei oder nach p einfuegen */
                                             {
                                             struct tnode *talloc();
                                             int cond;
                                             if (p == NULL) 
                                               {                           /* ein neues Wort */
                                               p = talloc();   /* einen neuen Knoten anlegen */
                                               strcpy(p->word, w);
                                               p->count = 1;
                                               p->left = NULL;
                                               p->right = NULL;
                                               } 
                                             else
                                               { 
                                               cond = strcmp(w, p->word);   /* Vergleich w mit Knoten */
                                               if (cond == 0)
                                                 p->count++;               /* Wort w schon vorhanden */
                                               else if (cond < 0)         /* w ist kleiner, links darunter */
                                                 p->left = insert_tree(p->left,w);
                                               else                        /* w ist groesser, rechts darunter */
                                                 p->right = insert_tree(p->right,w);
                                               }
                                             return(p);
                                             }
                                           
                                           void treeprint(struct tnode *p)
                                             /* Baum p rekursiv ausgeben */
                                             {
                                             if (p != NULL) 
                                               {
                                               treeprint(p->left);
                                               printf("%s (%4d)\n", p->word, p->count);
                                               treeprint(p->right);
                                               }
                                             }
                                           

    Ein weiteres Beispiel: Das folgende Programm liest aus der Quellatei die Wörter und gibt sie lexikographisch sortiert mit Häufigkeitsangabe in die Zieldatei aus.

                                           
                                           #include <stdio.h>
                                           #include <ctype.h>
                                           #include <string.h>
                                           #include <stdlib.h>
                                           
                                           #define MAX_WORT 200
                                           
                                           struct tnode 
                                             {
                                             char *wort;
                                             int zahl;
                                             struct tnode *links;
                                             struct tnode *rechts;
                                             };
                                           
                                           typedef struct tnode knoten;
                                           
                                           FILE *quelle, *ziel;
                                           
                                           FILE *eopen(char *file,char *mode);
                                           int lieswort(char *w, int lim);
                                           knoten *suche(knoten *p, char *w);
                                           inorder(knoten *p);
                                           char *merke_wort(char *s);
                                           
                                           
                                           int main(int argc, char *argv[]) 
                                             {   
                                             knoten *unterbaum, *suche();
                                             char progname[500];
                                             char wort [MAX_WORT];
                                             int c;
                                             progname = argv[0];
                                             if (argc != 3) 
                                               {
                                               fprintf(stderr,"Syntax: %s Quelldatei Zieldatei\n",progname);
                                               exit(1);
                                               }
                                             quelle = eopen(argv[1],"r");       
                                             unterbaum = NULL;
                                             while ((c = lieswort(wort, MAX_WORT)) != -1)
                                               if (c == 1)
                                                 unterbaum = suche(unterbaum, wort);
                                             fclose(quelle);
                                             ziel = eopen(argv[2],"w");
                                             inorder(unterbaum);
                                             fclose(ziel);
                                             return 0;
                                             }
                                           
                                           int lieswort(char *w, int lim) 
                                             /* lieswort  liest aus einer Datei ein Wort der Laenge lim in den
                                             ** Speicher, auf den w zeigt, und gibt 1 zurueck, falls es
                                             ** wirklich Alphazeichen gelesen hat, jedoch -1 im Fall zu
                                             ** grosser Wortlaenge. Falls Nicht-Alpha-Zeichen gelesen werden,
                                             ** wird 0 zurueckgegeben.
                                             */
                                             {   
                                             int c;
                                               
                                             while (!isalpha(c = getc(quelle))) 
                                               if (c == EOF) return -1;
                                             *w++ = c; 
                                             lim--;    
                                               
                                             while (isalpha(c = getc(quelle))  && (lim > 0)) 
                                               {    
                                               *w++ = c; lim--;   
                                               }
                                             if (lim == 0) 
                                               {     
                                               printf("%s: Error: Wort zu lang ", progname); 
                                               return -1; 
                                               }
                                             else 
                                               *w = '\0';
                                             if (lim < MAX_WORT) return 1; 
                                             else return 0;
                                             }
                                           
                                           FILE *eopen(char *file,char *mode) 
                                             {
                                             FILE *fp, *fopen();
                                           
                                             if ( (fp = fopen(file, mode)) != NULL )
                                                return fp;
                                             fprintf(stderr, 
                                                     "%s: Datei %s kann im Modus %s nicht geoeffnet werden\n",
                                                     progname, file, mode);
                                             exit(1);
                                             }
                                           
                                           knoten *suche(knoten *p, char *w)
                                             /* suche  durchsucht den Baum auf das Vorkommen des Wortes w,
                                             ** traegt es gegebenenfalls lexikographisch richtig ein bzw. erhoeht
                                             ** dessen Zahl und gibt den Pointer auf seinen Knoten zurueck.
                                             */
                                             {    
                                             int  cond;
                                             
                                             if (p == NULL) 
                                               {
                                               p = (knoten *) malloc(sizeof(knoten));
                                               p->wort = merke_wort(w);
                                               p->zahl = 1;
                                               p->links = p->rechts = NULL;
                                               }
                                             else if ((cond = strcmp(w, p->wort)) == 0)
                                               p->zahl++;
                                             else if (cond < 0)
                                               p->links = suche(p->links, w);
                                             else p->rechts = suche(p->rechts, w);
                                             return p ;
                                             }
                                           
                                           inorder(knoten *p) 
                                             /* inorder  gibt den Unterbaum, auf den p zeigt, in Inorder aus.
                                             */
                                             {    
                                             if (p != NULL)
                                               {  
                                               inorder(p->links);
                                               fprintf( ziel, "%4d %s\n", p->zahl, p->wort);
                                               inorder(p->rechts);
                                               }
                                             }
                                           
                                           char *merke_wort(char *s) 
                                             /*  merke_wort  speichert das Wort, auf dessen ersten Charakter s zeigt,
                                             **  und gibt einen Zeiger auf dessen neue Lokation an.
                                             */
                                             {   
                                             char *p;
                                             if ((p = (char *)malloc( strlen(s)+1 )) != NULL)
                                               strcpy(p, s);
                                             return p ;
                                             }
                                           

  • DIPLOMARBEITEN UND BÜCHER

    Diplomarbeiten zum Runterladen:

    Suche im Katalog:
    Architektur / Raumplanung
    Betriebswirtschaft - Funktional
    Erziehungswissenschaften
    Geowissenschaften
    Geschichtswissenschaften
    Informatik
    Kulturwissenschaften
    Medien- und Kommunikationswissenschaften
    Medizin
    Psychologie
    Physik
    Rechtswissenschaft
    Soziale Arbeit
    Sozialwissenschaften


    JOBS
    HOME | E-LEARNING | SITEMAP | LOGIN AUTOREN | SUPPORT | FAQ | KONTAKT | IMPRESSUM
    Virtual University in: Italiano - Français - English - Español
    VirtualUniversity, WEB-SET Interactive GmbH, www.web-set.com, 6301 Zug

    Partner:   Seminare7.de - PCopen.de - HTMLopen.de - WEB-SET.com - YesMMS.com - Ausbildung24.ch - Manager24.ch - Job und Karriere