3. Binääripuu, Java-toteutus /*-------------------------------------------------------------/ / Rajapinta SearchTree: binäärisen hakupuun käsittelyrajapinta / / Metodit: / / void insert( Comparable x ); / / - solun lisääminen puuhun / / void remove( Comparable x ); / / - solun poistaminen puusta / / void removemin(); / / - pienintä data-alkiota vastaavan solun poistaminen / / Comparable find( Comparable x ); / / - solun etsiminen / / Comparable findmin(); / / - pienintä data-alkiota vastaavan solun etsiminen / / Comparable findmax(); / / - suurinta data-alkiota vastaavan solun etsiminen / / boolean isempty(); / / - testi, onko puu tyhjä / / void makeempty(); / / - puun tyhjentäminen / / void printtree(); / / - puun tulostaminen / / Huomautuksia: / / - rahjapinta on sijoitettava samaan pakkaukseen kuin luokka / / BstNode ja tämän rajapinnan implementoiva luokka, / / esimerkiksi BST / / - rajapinta SearchTree mahdollistaa usean eri hakupuun / / toteutuksen, esim. BST, AVL, Red-Black Tree ym. / / - rajapinta on otettu teoksesta Weiss M. A: Data Structures / / & Problem Solving Using Java / / T. Harju 2002.10 / /-------------------------------------------------------------*/ public interface SearchTree void insert( Comparable x ); void remove( Comparable x ); void removemin(); Comparable find( Comparable x ); Comparable findmin(); Comparable findmax(); boolean isempty(); void makeempty(); void printtree(); /*-------------------------------------------------------------/ / Luokka BstNode: binäärisen hakupuun (BST) solu / / Kentät: / / Comparable item : solun data / / BstNode left : viite solun vasempaan lapsisoluun / / BstNode right : viite solun oikeaan lapsisoluun / / Konstruktorit: / / BstNode( Comparable it ) / / BstNode( Comparable it, BstNode lt, BstNode rt ) / / Metodit: / / - ei metodeja / / Huomautuksia: / / - luokka on sijoitettava samaan pakkaukseen kuin / / rajapinta SeachTree ja luokka BST / / - luokka yhdessä rajapinnan SearchTree kanssa mahdollistaa / / muunkin hakupuun kuin perus-bst:n toteutuksen. Tässä esim./ / on varauduttu AVL:n toteutukseen: luokka sisältää, tosin / / pois kommentoituna, AVL:n toteutusta helpottavan kentän / / "height" / / - luokan toteutus perustuu teoksessa Weiss M. A: Data / / Structures & Problem Solving Using Java julkaistuun / / koodiin. / / T. Harju 2002.10 / /-------------------------------------------------------------*/ class BstNode Comparable item; BstNode left; BstNode right; // int height = 0; //Varauduttu AVL:ään BstNode( Comparable it, BstNode lt, BstNode rt ) item = it; left = lt; right = rt; BstNode( Comparable it) this( it, null, null );
/*-------------------------------------------------------------/ / Luokka BST: binäärisen hakupuun (BST) implementointi toteut- / / tamalla rajapinta SearchTree / / Kentät: / / BstNode root : BST:n juurisolu / / Konstruktorit: / / BST() / / - luo tyhjän BST:n, jossa root = null / / Rajapinnan metodit: / / void insert( Comparable x ); / / - solun lisääminen puuhun / / void remove( Comparable x ); / / - solun poistaminen puusta / / void removemin(); / / - pienintä data-alkiota vastaavan solun poistaminen / / Comparable find( Comparable x ); / / - solun etsiminen / / Comparable findmin(); / / - pienintä data-alkiota vastaavan solun etsiminen / / Comparable findmax(); / / - suurinta data-alkiota vastaavan solun etsiminen / / boolean isempty(); / / - testi, onko puu tyhjä / / void makeempty(); / / - puun tyhjentäminen / / void printtree(); / / - puun tulostaminen / / Toteutustapa: / / Edellä olevat metodit ovat kaikki julkisia ja muodostavat / / siten julkisen ohjelmointirajapinnan. Varsinainen toteutus / / on kuitenkin kätketty muilta kuin luokan perillisillä paitsi/ / yksinkertaisimmilla metodeilla, esim. isempty(). Rajapinta- / / metodit vain kutsuvat toteutusmetodeja, jotka ovat näky- / / vyydeltään "protected". Katso tämä varsinainen toteutus / / koodista. / / Huomautuksia: / / - luokka on sijoitettava samaan pakkaukseen kuin luokka / / BstNode ja rajapinta SearchTree / / - luokan toteutus perustuu teoksessa Weiss M. A: Data / / Structures & Problem Solving Using Java julkaistuun / / koodiin. / / T. Harju 2002.10 / /-------------------------------------------------------------*/ public class BST implements SearchTree protected BstNode root; public BST() root = null; /*--- Rajapinnan SearcTree toteutus ---*/ public void insert( Comparable x ) root = insert( x, root ); public void remove( Comparable x ) root = remove( x, root ); public void removemin() root = removemin( root ); public Comparable find( Comparable x ) return find( x, root ).item; public Comparable findmin() return findmin( root ).item; public Comparable findmax() return findmax( root ).item; public boolean isempty() return root == null; public void makeempty() root = null; public int height() // BST:n korkeus, ei sisälly rajapintaan return height( root ); public void printtree() printtree( root );
/*--- Sisäiset metodit: varsinainen toteutuskoodi ---*/ protected BstNode insert( Comparable x, BstNode t ) if ( t == null ) t = new BstNode( x, null, null ); if ( x.compareto( t.item ) < 0 ) t.left = insert( x, t.left ); if ( x. compareto( t.item ) > 0 ) t.right = insert( x, t.right ); System.out.println( "BST insert: duplicate item" ); protected BstNode remove( Comparable x, BstNode t ) if ( t == null ) System.out.println( "BST remove: item not found" ); if ( x.compareto( t.item ) < 0 ) t.left = remove( x, t.left ); if ( x.compareto( t.item ) > 0 ) t.right = remove( x, t.right ); if ( t.left!= null && t.right!= null ) t.item = findmin( t.right ).item; t.right = removemin( t.right ); t = ( ( t.left!= null )? t.left : t.right ); protected BstNode removemin( BstNode t ) if ( t == null ) System.out.println( "BST removemin: item not found" ); if ( t.left!= null ) t.left = removemin( t.left ); t = t.right; protected BstNode find( Comparable x, BstNode t ) while ( t!= null ) if ( x.compareto( t.item ) < 0 ) t = t.left; if ( x.compareto( t.item ) > 0 ) t = t.right; System.out.println( "BST find: item not found" ); protected BstNode findmin( BstNode t ) if ( t!= null ) System.out.println( "BST findmin: item not found" ); while ( t.left!= null ) t = t.left; protected BstNode findmax( BstNode t ) if ( t!= null ) System.out.println( "BST findmax: item not found" ); while ( t.right!= null ) t = t.right; protected int height( BstNode t ) int u, v; if ( t == null ) return -1; u = height( t.left ); v = height( t.right ); return ( u > v )? u + 1 : v + 1; protected void printtree( BstNode t ) if ( t.left!= null ) printtree( t.left ); for ( int i = 0; i < 2*height( t ); ++i ) System.out.print( " " ); System.out.println( t.item ); if ( t.right!= null ) printtree( t.right ); public class BstDemo public static void main( String[] args ) SearchTree puu = new BST(); System.out.println( "Anna BST:hen sijoitettavat luvut, lopuksi - 999" ); int luku = Lue.kluku(); while ( luku!= -999 ) puu.insert( new Integer( luku ) ); luku = Lue.kluku(); puu.printtree();
4. BST, C-toteutus /* BST.H - binäärisen hakupuun (Binary Search Tree) käsittelyyn */ /* liittyviä määrittelyjä. */ /* Käyttö: */ /* - omaan ohjelmaan #include "bst.h", jonka on oltava */ /* hakemistossa, mistä kääntäjä sen löytää */ /* - tiedosto bst.c linkitettävä mukaan ohjelmaan */ /* Sisältö: */ /* insnode() : lisää noden BST:hen, myös tyhjään */ /* find() : etsii noden BST:stä */ /* findmin() : etsii BST:n pienimmän data-alkion noden */ /* findmax() : etsii BST:n suurimman data-alkion noden */ /* delnode() : poistaa noden BST:stä */ /* delbst : poistaa koko BST:n */ /* height() : palauttaa BST:n korkeuden */ /* printbst() : tulostaa BST:n sisällön sisäjärjstyksessä */ /* Teokseen Weiss: Data Structures and Algorithm Analysis perustuen */ /* implementoinut Timo Harju 1999.11, 2000.12 */ #ifndef _BST.H #define _BST.H typedef int item_type; /* BST:n datan tyyppi */ typedef struct node *link; /* Pointteri nodeen */ struct node /* Node: */ item_type item; /* data */ link left; /* pointteri vasempaan oksaan */ link right; /* ja oikeaan oksaan */ ; typedef link BST; /* Vaihtoehtoinen nimi pointterille */ typedef struct node Node; /* ja itse nodelle */ /* Funktioiden prototyypit */ link insnode( BST T, item_type a ); link find( BST T, item_type x ); link findmin( BST T ); link findmax( BST T ); link delnode( BST T, item_type a ); void delbst( BST T ); int height( BST T ); void printbst( BST T ); #endif /* BST.C - binäärisen hakupuun (Binary Search Tree) käsittelyyn */ /* liittyviä funktioita */ /* Käyttö: */ /* - omaan ohjelmaan #include "bst.h", jonka on oltava */ /* hakemistossa, mistä kääntäjä sen löytää */ /* - tämä tiedosto bst.c linkitettävä mukaan ohjelmaan */ /* Sisältö: */ /* insnode() : lisää noden BST:hen, myös tyhjään */ /* find() : etsii noden BST:stä */ /* findmin() : etsii BST:n pienimmän data-alkion noden */ /* findmax() : etsii BST:n suurimman data-alkion noden */ /* delnode() : poistaa noden BST:stä */ /* delbst() : poistaa koko BST:n */ /* height() : palauttaa BST:n korkeuden */ /* printbst() : tulostaa BST:n sisällön sisäjärjstyksessä */ /* Teokseen Weiss: Data Structures and Algorithm Analysis perustuen */ /* implementoinut Timo Harju 1999.11, 2000.12 */ #include <stdio.h> #include <stdlib.h> #include "bst.h" link insnode( BST T, item_type a ) if ( T == NULL ) if ( ( T = ( link ) malloc( sizeof( struct node ) ) ) == NULL ) printf( "insnode: muistin varaaminen epäonnistui\n" ); exit(1); T->item = a; T->left = T->right = NULL; if ( a < T->item ) T->left = insnode( T->left, a ); if ( a > T->item ) T->right = insnode( T->right, a ); link find( BST T, item_type x ) if ( T == NULL ) if ( x < T->item ) return find( T->left, x ); if ( x > T->item ) return find( T->right, x );
link findmin( BST T ) if ( T!= NULL ) while( T->left ) T = T->left; link findmax( BST T ) if ( T!= NULL ) while( T->right ) T = T->right; link delnode( BST T, item_type a ) link temp, child; if ( T == NULL ) printf( "Tuhottavaa ei löydy" ); if ( a < T->item ) T->left = delnode( T->left, a ); if ( a > T->item ) T->right = delnode( T->right, a ); if ( T->left && T->right ) temp = findmin( T->right ); T->item = temp->item; T->right = delnode( T->right, T->item ); temp = T; if ( T->left == NULL ) child = T->right; if ( T->right == NULL ) child = T->left; free( temp ); return child; void delbst( BST T ) link p, q; if ( T!= NULL ) p = T->left; q = T->right; free( T ); delbst( p ); delbst( q ); int height( BST T ) int u, v; if ( T == NULL ) return -1; u = height( T->left ); v = height( T->right ); if ( u > v ) return u+1; return v+1; void printbst( BST T ) int n, i; if ( T!= NULL ) printbst( T->left ); n = height( T ); /* Tässä yritetään saada */ for ( i = 0 ; i < 2 * n; ++i ) /* tulostus edes vähän */ printf( " " ); /* puuta muistuttavaksi */ printf( "%d\n", T->item ); printbst( T->right ); /* ------------------------------------------------------------ */ /* TIETORAKENTEET JA ALGORITMIT: BSTDemo */ /* Varsinaiset BST:n käsittelyrutiinit ovat tiedostoissa bst.h */ /* (tietotyypit ja funktioiden prototyypit) sekä bst.c (koodi) */ /* T. Harju 1999.11, 2000.12 */ /* ------------------------------------------------------------ */ #include <stdio.h> #include <conio.h> #include "bst.h" void main( void ) BST Tree = NULL, p; int val, luku; clrscr(); printf( "BST:n (Binary Search Tree) käsittelyä\n\n"); printf( "Anna puuhun sijoitettavat luvut, lopuksi -9999\n" ); printf( ": " ); scanf( "%d", &luku ); while ( luku!= -9999 ) Tree = insnode( Tree, luku ); printf( ": " ); scanf( "%d", &luku );
/* Sitten vaan kokeillaan lisäystä, poistoa ja koko listan hävittämistä. */ /* Siinä sivussa tulee etsiminenkin testatuksi. */ 6. BST, vaatimaton java-toteutus do do clrscr(); printf( "Lisäys... 1\n" ); printf( "Poisto... 2\n" ); printf( "BST:n tuhoaminen... 3\n" ); printf( "Lopetus... 0\n" ); printf( "\nvalintasi: " ); scanf( "%d", &val ); while ( ( val < 0 ) ( val > 3 ) ); switch ( val ) case 1: /* Lisäys */ printf( "Anna lisätttvä alkio: " ); scanf( "%d", &luku ); Tree = insnode( Tree, luku ); case 2: /* Poisto */ printf( "Mikä alkio poistetaan: " ); scanf( "%d", &luku ); p = find( Tree, luku ); if ( p == NULL ) printf( "Ei löydy!" ); Tree = delnode( Tree, luku ); case 3: /* Puun hävittäminen */ delbst( Tree ); Tree = NULL; default: while( val!= 0 ); /* Luokka BST: vähän BST-luokan alkua / / TH 2003.10 */ class Node // BST:n solu: data + linkit oksiin Comparable item; // Comparable on Javassa määr. rajapinta Node left; Node right; public Node() // Solun konstruktori item = null; left = right = null; public class BST private Node root; // Puun juuri public BST() // Konstruktori root = null; // Solun lisäys public Node insnode( Node T, Comparable a ) if ( T == null ) T = new Node(); T.item = a; T.left = T.right = null; if ( a.compareto( T.item ) < 0 ) T.left = insnode( T.left, a ); if (a.compareto( T.item ) > 0 ) T.right = insnode( T.right, a ); public Node getroot() // Palauttaa juuren return root; public void setroot( Node p ) // Asettaa juuren root = p; void prtree( Node p, int h ) // Tulostetaan puu if ( p!= null ) prtree( p.right, h + 1 ); // sisäjärjestyksessä for ( int i = 0; i < h; ++i ) // jossakin määrin puun System.out.print( " " ); // muodossa System.out.println( p.item ); prtree( p.left, h + 1 );
/* Testiohjelma luokan BST kokeilemiseksi / / TH 2003.10 */ 6. PQ, C-toteutus public class BSTdemo public static void main( String[] args ) BST puu = new BST(); // Luodaan BST System.out.println( "Anna BST:hen sijoitettavat kokonaisluvut yksitellen." ); System.out.println( "Anna lopuksi -999" ); int luku= Lue.kluku(); // Ensimmäinen sijoitettava if ( luku!= -999 ) // Tehdään siitä juuri puu.setroot( puu.insnode( puu.getroot(), new Integer( luku ) ) ); puu.prtree( puu.getroot(), 0 ); System.out.println( "" ); luku= Lue.kluku(); while ( luku!= -999 ) puu.insnode( puu.getroot(), new Integer( luku ) ); puu.prtree( puu.getroot(), 0 ); System.out.println( "" ); luku= Lue.kluku(); /* PQ.H - priorisoidun jonon (Priority Queue) käsittelyyn */ /* liittyviä määrittelyjä, PQ:n toteutus taulukossa */ /* olevana binäärisenä kasana (heap) */ /* Käyttö: */ /* - omaan ohjelmaan #include "pq.h", jonka on oltava */ /* hakemistossa, mistä kääntäjä sen löytää */ /* - tiedosto pq.c linkitettävä mukaan ohjelmaan */ /* Sisältö: */ /* creapq() : luo PQ:n */ /* insert() : lisää alkion PQ:un */ /* delmin() : poistaa PQ:n pienimmän alkion */ /* printpq() : tulostaa PQ:n (vast. puun tasojärjestyksessä ) */ /* delpq() : tuhoaa PQ:n */ /* Teokseen Weiss: Data Structures and Algorithm Analysis perustuen */ /* implementoinut Timo Harju 1999.12, 2000.12 */ #ifndef _PQ.H #define _PQ.H typedef int item_type; /* PQ:n datan tyyppi */ struct pqstruct int maxsize; /* PQ:n maksimi alkiomäärä */ int size; /* PQ:n todellinen alkiomäärä */ item_type *items; /* Pointteri PQ:n datataulukkoon */ ; typedef struct pqstruct *PQ; /* Pointterityyppi PQ:un */ /* Funktioiden prototyypit */ PQ creapq( int n ) ; void insert( PQ H, item_type a ); item_type delmin( PQ H ); void printpq( PQ H ); void delpq( PQ H ); #endif
/* PQ.C - priorisoidun jonon (Priority Queue) käsittelyyn */ /* liittyviä funktioita, PQ:n toteutus taulukossa */ /* olevana binäärisenä kasana (heap) */ /* Käyttö: */ /* - omaan ohjelmaan #include "pq.h", jonka on oltava */ /* hakemistossa, mistä kääntäjä sen löytää */ /* - tämä tiedosto pq.c linkitettävä mukaan ohjelmaan */ /* Sisältö: */ /* creapq() : luo PQ:n */ /* insert() : lisää alkion PQ:un */ /* delmin() : poistaa PQ:n pienimmän alkion */ /* printpq() : tulostaa PQ:n (vast. puun tasojärjestyksessä ) */ /* delpq() : tuhoaa PQ:n */ /* Teokseen Weiss: Data Structures and Algorithm Analysis perustuen */ /* implementoinut Timo Harju 1999.12, 2000.12 */ #include <stdio.h> #include <stdlib.h> #include "PQ.H" #ifndef MIN_DATA #define MIN_DATA -32767 /* Pienin mahdollinen data-alkio (int) */ #endif PQ creapq( int n ) PQ H; void insert( PQ H, item_type a ) int i; if ( H->size == H->maxSize ) printf( "PQ on täynnä\n" ); i = ++H->size; while( H->items[i/2] > a ) H->items[i] = H->items[i/2]; i /= 2; H->items[i] = a; item_type delmin( PQ H ) int i, child; item_type mini, last; if ( H->size == 0 ) printf( "PQ on tyhjä\n" ); return H->items[0]; mini = H->items[1]; last = H->items[H->size--]; H = ( PQ ) malloc( sizeof( struct pqstruct ) ); if ( H == NULL ) printf( "PQ:n muistinvaraus ei onnistunut\n" ); exit( 1 ); H->items = ( item_type * ) malloc( ( n + 1 ) * sizeof( item_type ) ); if ( H->items == NULL ) printf( "PQ:n datan muistinvaraus ei onnistunut\n" ); exit( 2 ); H->maxSize = n; H->size = 0; H->items[0] = MIN_DATA; return H; for ( i = 1; 2*i <= H->size; i = child ) child = 2*i; if ( ( child!= H->size ) && ( H->items[child+1] < H->items[child] ) ) ++child; if ( last > H->items[child] ) H->items[i] = H->items[child]; H->items[i] = last; return mini; void printpq( PQ H ) int i; for ( i = 1; i <= H->size; ++i ) printf( "%d ", H->items[i] );
void delpq( PQ H ) free( H->items ); free( H ); H = NULL;