This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA
p o i n t s ;
11 12 13
typedef v a l a r r a y <double> vec ; typedef v a l a r r a y
14 15 16 17 18
/ / Abstand des Punkts pos zum Ursprung double norm ( const vec& a ) { r e t u r n s q r t ( ( a ∗ a ) . sum ( ) ) ; }
19 20 21 22 23
/ / Abstand z w e i e r Punkte double d i s t ( const vec& a , const vec& b ) { r e t u r n norm ( a − b ) ; }
24 25 26
/ / Punkt a u f Gerade durch Punkt pos i n Richtung d i r / / m i t k l e i n s t e m Abstand zu Ursprung ( o r t h o g o n a l e P r o j e k t i o n )
7
27 28 29
GEOMETRIE
24
vec p r o j ( const vec& pos , const vec& d i r ) { r e t u r n pos − ( pos ∗ d i r ) . sum ( ) / ( d i r ∗ d i r ) . sum ( ) ∗ d i r ; }
30 31 32 33 34
/ / Abstand Punkt−Gerade double d i s t ( const vec& pos , const vec& d i r , const vec& p t ) { r e t u r n norm ( p r o j ( pos − pt , d i r ) ) ; }
35 36 37 38 39 40
/ / S c h n i t t p u n k t Gerade durch pos i n Richtung d i r / / m i t Gerade / Ebene durch Ursprung m i t Normale norm vec i s e c t ( const vec& pos , const vec& d i r , const vec& norm ) { r e t u r n pos − ( pos ∗ norm ) . sum ( ) / ( d i r ∗ norm ) . sum ( ) ∗ d i r ; }
41 42 43 44 45 46 47
/ / 2D−S c h n i t t p u n k t der Geraden durch Punkte a1−a2 und b1−b2 vec i s e c t ( const vec& a1 , const vec& a2 , const vec& b1 , const vec& b2 ) { double temp [ ] = { a1 [ 1 ] − a2 [ 1 ] , a2 [ 0 ] − a1 [ 0 ] } ; vec norm ( temp , 2 ) ; r e t u r n i s e c t ( b1 − a1 , b2 − b1 , norm ) + a1 ; }
48 49 50 51 52 53 54
/ / S c h n i t t p u n k t Gerade durch pos i n Richtung d i r / / m i t K r e i s / Kugel um Ursprung m i t Radius rad i n l i n e vecvec i s e c t ( const vec& pos , const vec& d i r , double rad ) { double pp = ( pos ∗ pos ) . sum ( ) , dd = ( d i r ∗ d i r ) . sum ( ) , pd = ( pos ∗ d i r ) . sum ( ) , r r = rad ∗ rad , d i s = pd ∗ pd − dd ∗ ( pp − r r ) ;
55
i f ( d i s > EPS) { vecvec r e s ( pos , 2 ) ; dis = sqrt ( dis ) ; r e s [ 0 ] −= ( pd + d i s ) / dd ∗ d i r ; r e s [ 1 ] −= ( pd − d i s ) / dd ∗ d i r ; return res ; } else i f ( d i s > −EPS) { vecvec r e s ( pos , 1 ) ; r e s [ 0 ] −= pd / dd ∗ d i r ; return res ; }
56 57 58 59 60 61 62 63 64 65 66 67
r e t u r n vecvec ( ) ;
68 69
}
7.2
Dreiecke und Liniensegmente
1 2 3
# include # include
4 5
using namespace s t d ;
6 7
const double PI = 2 ∗ acos ( 0 ) , EPS = 1e−9;
8 9
typedef v a l a r r a y <double> vec ;
10 11 12 13 14 15
/ / Flaeche des durch a und b aufgespannten Parallelogramms / / p o s i t i v , wenn Winkel zwischen a und b p o s i t i v double sgn area ( const vec& a , const vec& b ) { return a [ 0 ] ∗ b [ 1 ] − a [ 1 ] ∗ b [ 0 ] ; }
16 17 18
/ / p o s i t i v , wenn a−b−c im Gegenuhrzeigersinn ( math . p o s i t i v ) l i e g e n double sgn area ( const vec& a , const vec& b , const vec& c ) {
7
GEOMETRIE
r e t u r n sgn area ( b − a , c − a ) ;
19 20
25
}
21 22 23 24 25
/ / Dreiecksflaeche double area ( const vec& a , const vec& b , const vec& c ) { r e t u r n 0 . 5 ∗ f a b s ( sgn area ( a , b , c ) ) ; }
26 27 28 29 30 31 32 33
/ / D r e i e c k s f l a e c h e aus Se it en la en ge n double area ( double a , double b , double c ) { i f ( a < b ) swap ( a , b ) ; i f ( b < c ) swap ( b , c ) ; i f ( a < b ) swap ( a , b ) ; r e t u r n 0.25 ∗ s q r t ( ( a + ( b + c ) ) ∗ ( c − ( a − b ) ) ∗ ( c + ( a − b ) ) ∗ ( a + ( b − c ) ) ) ; }
34 35 36 37 38
/ / t r u e , wenn a und b verschiedene Vorzeichen haben i n l i n e bool pos neg ( double a , double b ) { r e t u r n ( a < 0 && 0 < b ) | | ( b < 0 && 0 < a ) ; }
39 40 41 42 43 44 45 46
/ / t r u e , wenn Punkt d i n D r e i e c k m i t bool i n s i d e ( const vec& a , const vec& double x = sgn area ( c , b , a ) ; r e t u r n pos neg ( x , sgn area ( a , b , && pos neg ( x , sgn area ( b , c , && pos neg ( x , sgn area ( c , a , }
Eckpunkten a−b−c l i e g t b , const vec& c , const vec& d ) { d)) d)) d));
47 48 49 50 51 52
/ / t r u e , wenn Punkt c i n a c h s e n p a r a l l e l e m Rechteck durch Punkt a und b l i e g t bool i n s i d e ( const vec& a , const vec& b , const vec& c ) { r e t u r n min ( a [ 0 ] , b [ 0 ] ) < c [ 0 ] + EPS && max ( a [ 0 ] , b [ 0 ] ) > c [ 0 ] − EPS && min ( a [ 1 ] , b [ 1 ] ) < c [ 1 ] + EPS && max ( a [ 1 ] , b [ 1 ] ) > c [ 1 ] − EPS ; }
53 54 55 56 57
/ / t r u e , wenn c a u f Segment a−b l i e g t bzw . g l e i c h a oder b i s t bool on seg ( const vec& a , const vec& b , const vec& c ) { r e t u r n i n s i d e ( a , b , c ) && f a b s ( sgn area ( a , b , c ) ) < EPS ; }
58 59 60 61 62 63
/ / S c h n i t t der Liniensegmente a1−a2 und b1−b2 / / 0 = k e i n S c h n i t t , 1 = S c h n i t t , −1 = Beruehrung i n t i s e c t ( const vec& a1 , const vec& a2 , const vec& b1 , const vec& b2 ) { double da1 = sgn area ( b1 , b2 , a1 ) , da2 = sgn area ( b1 , b2 , a2 ) , db1 = sgn area ( a1 , a2 , b1 ) , db2 = sgn area ( a1 , a2 , b2 ) ;
64
i f ( pos neg ( da1 , da2 ) && pos neg ( db1 , db2 ) ) r e t u r n 1 ; i f ( on seg ( a1 , a2 , b1 ) | | on seg ( a1 , a2 , b2 ) | | on seg ( b1 , b2 , a1 ) | | on seg ( b1 , b2 , a2 ) ) r e t u r n −1; return 0;
65 66 67 68 69
}
Abstand eines Punktes, Abstand eines anderen Segments.
7.3
Kreise
1 2 3 4 5
/ / S c h n i t t p u n k t e von K r e i s um 0 m i t Radius r 1 m i t K r e i s um Punkt pos m i t Radius r 2 vecvec i s e c t ( double r1 , vec pos , double r 2 ) { double d2 = ( pos ∗ pos ) . sum ( ) , d = s q r t ( d2 ) ; r 1 ∗= r 1 ; r 2 ∗= r 2 ; double x = 0 . 5 ∗ ( d2 + r 1 − r 2 ) / d , y2 = r 1 − x ∗ x ;
6 7 8 9
i f ( y2 > EPS) { double norma [ ] = { −pos [ 1 ] , pos [ 0 ] } ; vec norm ( norma , 2 ) ;
7
GEOMETRIE
vecvec r ( x / d ∗ pos , 2 ) ; y2 = s q r t ( y2 ) ; r [ 0 ] += y2 / d ∗ norm ; r [ 1 ] −= y2 / d ∗ norm ; return r ; } else i f ( y2 > −EPS) { r e t u r n vecvec ( x / d ∗ pos , 1 ) ; } r e t u r n vecvec ( ) ;
10 11 12 13 14 15 16 17 18 19
26
}
Kreis durch drei Punkte, Kreis durch zwei Punkte mit geg. Radius.
7.4
Polygone
Die N Punkte eines Polygons werden mit (xi , yi ) fur ¨ i = 1, . . . , N bezeichnet. Konvention: (x0 , y0 ) = (xN , yN ). ¨ Die vorzeichenbehaftete Flache A berechnet sich wie folgt: N
A=
1X xi−1 yi − xi yi−1 2 i=1
¨ Bei Polygonen mit ganzzahligen Koordinaten gilt fur A, die Anzahl der Gitterpunkte auf dem Rand B ¨ die Flache und die derjenigen im Innern I: B I =A− +1 2 7.4.1
Punkt in Polygon
1
# include
2 3 4
# define MAX 1024 # define EPS 1e−7
5 6 7 8
struct point { double x , y ; };
9 10 11 12 13 14 15 16
s t r u c t polygon { int n; p o i n t p [MAX ] ; p o i n t &operator [ ] ( i n t i ) { return p [ i ] ; } };
17 18 19 20 21
i n l i n e double d i s t ( const p o i n t &a , const p o i n t &b ) { double dx = a . x − b . x , dy = a . y − b . y ; r e t u r n s q r t ( dx ∗ dx + dy ∗ dy ) ; }
22 23 24
bool c o n t a i n s ( polygon &P , p o i n t &p ) { bool i n s i d e = f a l s e ;
25 26 27 28 29
f o r ( i n t j = P . n − 1 , i = 0 ; i < P . n ; j = i ++) { i f ( f a b s ( d i s t ( p , P [ j ] ) + d i s t ( p , P [ i ] ) − d i s t (P [ j ] , P [ i ] ) ) < EPS) { r e t u r n t r u e ; / / t r u e = Rand g e h o e r t m i t zum Polygon }
30 31 32 33 34 35 36
i f ( min (P [ j ] . y , P [ i ] . y ) <= p . y && max (P [ j ] . y , P [ i ] . y ) > p . y && ( p . y − P [ j ] . y ) ∗ (P [ i ] . x − P [ j ] . x ) / (P [ i ] . y − P [ j ] . y ) > p . x − P [ j ] . x ) { inside = ! inside ; } } return i n s i d e ;
7
37
GEOMETRIE
}
7.4.2
Konvexe Hulle ¨ (Graham’s Scan)
1 2
27
# include # include
3 4
using namespace s t d ;
5 6 7
const long double EPS = 1e−5; const i n t MAXPOINTS = 1005;
8 9 10 11 12
struct point { long double x , y ; } p o i n t s [ MAXPOINTS ] , h u l l [ MAXPOINTS ] ; i n t npoints , n h u l l ;
13 14 15 16
long double signedArea ( const p o i n t & a , const p o i n t & b , const p o i n t & c ) { return a . x ∗ b . y − b . x ∗ a . y + b . x ∗ c . y − c . x ∗ b . y + c . x ∗ a . y − a . x ∗ c . y ; }
17 18 19 20
long double s q r d i s t ( const p o i n t & a , const p o i n t & b ) { return ( a . x − b . x ) ∗ ( a . x − b . x ) + ( a . y − b . y ) ∗ ( a . y − b . y ) ; }
21 22 23
bool bySignedArea ( const p o i n t & a , const p o i n t & b ) { long double sa = signedArea ( p o i n t s [ 0 ] , a , b ) ;
24
r e t u r n ( f a b s ( sa ) < EPS ) ? ( sqrdist ( points [0] , a ) < sqrdist ( points [0] , b ) ) : ( sa > 0 ) ;
25 26 27 28
}
29 30 31 32
void f i n d m i n p o i n t ( ) { long double minx = p o i n t s [ 0 ] . x , miny = p o i n t s [ 0 ] . y ; int currentmin = 0;
33
f o r ( i n t i = 1 ; i < n p o i n t s ; ++ i ) { i f ( p o i n t s [ i ] . y < miny | | ( p o i n t s [ i ] . y == miny && p o i n t s [ i ] . x < minx ) ) { minx = p o i n t s [ i ] . x ; miny = p o i n t s [ i ] . y ; currentmin = i ; } }
34 35 36 37 38 39 40 41
/ / exchange min p o i n t w i t h p o i n t [ 0 ] swap ( p o i n t s [ c u r r e n t m i n ] , p o i n t s [ 0 ] ) ;
42 43 44
}
45 46 47 48 49
void c o n v e x h u l l ( ) { findminpoint ( ); s o r t ( p o i n t s + 1 , p o i n t s + n p o i n t s , bySignedArea ) ;
50 51 52
hull [0] = points [ 0 ] ; nhull = 1;
53 54 55 56 57 58
f o r ( i n t i = 1 ; i < n p o i n t s ; ++ i ) { / / h i e r anpassen , wenn k o l l i n e a r e punkte m i t aufgenommen werden s o l l e n while ( n h u l l > 1 && signedArea ( h u l l [ n h u l l − 2 ] , h u l l [ n h u l l − 1 ] , p o i n t s [ i ] ) < EPS ) { −−n h u l l ; }
59 60
h u l l [ n h u l l ++] = p o i n t s [ i ] ;
7
28
}
61 62
GEOMETRIE
}
7.4.3
Clipping an Halbebene bzw. Gerade
1 2 3
# include
4 5 6 7
struct point { double x , y ; };
8 9
const i n t MAX = 1510
10 11 12 13 14 15 16 17
s t r u c t polygon { p o i n t p [MAX ] ; int n; p o i n t & operator [ ] ( i n t i ) { return p [ i ] ; } } poly , c l i p p e d [ 2 ] ;
18 19
double n o r m a l i z e ;
20 21 22 23 24
double signedPolygonArea ( polygon &p ) { double a = 0 ; f o r ( i n t i = 1 ; i < p . n ; ++ i ) a += p [ i −1]. x ∗ p [ i ] . y − p [ i ] . x ∗ p [ i −1]. y ;
25
a += p [ p . n −1]. x ∗ p [ 0 ] . y − p [ 0 ] . x ∗ p [ p . n −1]. y ;
26 27
return a / 2 ;
28 29
}
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
void i n s e r t ( polygon &p , p o i n t &a ) { i f ( p . n > 0) { i f ( p [ p . n −1]. x == a . x && p [ p . n −1]. y == a . y ) return ; } p [ p . n ++] = a ; } double sa ( p o i n t & a , p o i n t & b , p o i n t & c ) { return ( a . x ∗ b . y − a . y ∗ b . x + b . x ∗ c . y − b . y ∗ c . x + c . x ∗ a . y − a . x ∗ c . y ) ∗ normalize ; } p o i n t i n t e r s e c t ( p o i n t & p1 , p o i n t & p2 , p o i n t & p3 , p o i n t & p4 ) { double a1 = p2 . y − p1 . y , b1 = p1 . x − p2 . x ; double c1 = p1 . x∗p2 . y − p2 . x∗p1 . y ; double a2 = p4 . y − p3 . y , b2 = p3 . x − p4 . x ; double c2 = p3 . x∗p4 . y − p4 . x∗p3 . y ;
46 47 48 49 50
double d = a1∗b2 − a2∗b1 ; point p ; p . x = ( c1∗b2 − c2∗b1 ) / d ; p . y = ( a1∗c2 − a2∗c1 ) / d ;
51 52 53 54 55 56 57 58 59
return p ; } void d o c l i p p i n g ( p o i n t & a , p o i n t & b , polygon& i n p u t , polygon& o u t p u t ) { output . n = 0; f o r ( i n t k = 0 ; k < i n p u t . n ; ++k ) { i n t i = k , i p p = ( k +1) % i n p u t . n ; double s a i = sa ( a , b , i n p u t [ i ] ) ; double s a i p p = sa ( a , b , i n p u t [ i p p ] ) ;
7
GEOMETRIE
29
60
i f ( s a i >= 0 && s a i p p >= 0 ) i n s e r t ( output , i n p u t [ ipp ] ) ; else i f ( s a i >= 0 && s a i p p < 0 ) { point c = i n t e r s e c t (a , b , input [ i ] , input [ ipp ] ) ; i n s e r t ( output , c ) ; } else i f ( s a i < 0 && s a i p p >= 0 ) { point c = i n t e r s e c t (a , b , input [ i ] , input [ ipp ] ) ; i n s e r t ( output , c ) ; i n s e r t ( output , i n p u t [ ipp ] ) ; } else { a s s e r t ( s a i < 0 && s a i p p < 0 ) ; }
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
} } i n t main ( ) { int currentclipped = 0; / / TODO here : / / i n p u t polygon i n t o both p o l y and c l i p p e d [ 0 ] ! !
81
/ / n o r m a l i z e t h e d i r e c t i o n o f t h e p o i n t s o f t h e polygon n o r m a l i z e = signedPolygonArea ( p o l y ) ; i f ( n o r m a l i z e > 0 ) n o r m a l i z e = 1 ; else n o r m a l i z e = −1; f o r ( i n t i = 0 ; i < p o l y . n−1; ++ i ) { d o c l i p p i n g ( p o l y [ i ] , p o l y [ i + 1 ] , c l i p p e d [ c u r r e n t c l i p p e d ] , c l i p p e d [1− c u r r e n t c l i p p e d ] ) ; c u r r e n t c l i p p e d = 1− c u r r e n t c l i p p e d ; } d o c l i p p i n g ( p o l y [ p o l y . n −1] , p o l y [ 0 ] , c l i p p e d [ c u r r e n t c l i p p e d ] , c l i p p e d [1− c u r r e n t c l i p p e d ] ) ; c u r r e n t c l i p p e d = 1− c u r r e n t c l i p p e d ; return 0;
82 83 84 85 86 87 88 89 90 91 92
}
7.5
Rasterung von Linien/Kreisen (Bresenham)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/ / r u f t do something ( x , y ) m i t a l l e n ( x , y ) auf , / / d i e e i n e g e r a s t e r t e L i n i e von ( x0 , y0 ) nach ( x1 , y1 ) b i l d e n void l i n e ( i n t x0 , i n t y0 , i n t x1 , i n t y1 ) { i n t dx = x1 − x0 , dy = y1 − y0 ; i n t i n c r E = 2 ∗ dy , incrNE = 2 ∗ ( dy − dx ) ; i n t d = 2 ∗ dy − dx , x = x0 , y = y0 ; do something ( x , y ) ; while ( x < x1 ) { i f ( d > 0 ) { d += incrNE ; ++y ; } else d += i n c r E ; do something (++ x , y ) ; } } / / r u f t do something ( x , y ) m i t a l l e n ( x , y ) auf , / / d i e einen g e r a s t e r t e n A c h t e l k r e i s um den Ursprung b i l d e n void c i r c l e ( i n t r a d i u s ) { i n t d e l t a E = 3 , deltaSE = −2 ∗ r a d i u s + 5 ; i n t d = 1 − radius , x = 0 , y = radius ; do something ( x , y ) ; while ( x < y ) { i f ( d < 0 ) d += d e l t a E ; else { d += deltaSE ; deltaSE += 2 ; −−y ; } d e l t a E += 2 ; deltaSE += 2 ; do something (++ x , y ) ; } }
8
DATENSTRUKTUREN
8 8.1
30
Datenstrukturen Disjunkte Mengen (Union-Find)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# include # include
8.2
Heap
In der STL gibt es make heap, is heap, sort heap, push heap und pop heap. Achtung: Diese Funktionen stellen das ¨ großte Element an die Spitze des Heaps. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/ / h i e r m i t i n t , aber es r e i c h t , wenn o p e r a t o r < d e f i n i e r t i s t void l i f t ( v e c t o r & v , i n t i ) { for ( int j ; i > 0; i = j ) { j = ( i − 1) / 2; i f ( ! ( v [ j ] < v [ i ] ) ) break ; swap ( v [ i ] , v [ j ] ) ; } } void s i n k ( v e c t o r & v , i n t i ) { for ( i n t j ; ( j = 2 ∗ i + 1) < i n t ( v . size ( ) ) ; i = j ) { i f ( j + 1 < i n t ( v . s i z e ( ) ) && v [ j ] < v [ j + 1 ] ) ++ j ; i f ( ! ( v [ i ] < v [ j ] ) ) break ; swap ( v [ i ] , v [ j ] ) ; } }
8.3
Fenwick-Baum
1 2 3
# include
4 5 6 7 8 9 10 11
/ / v [ i ] += k void i n c r ( v e c t o r & a , i n t i , i n t k ) { a [ i ] += k ; while ( i > 0 ) { i &= i − 1 ; a [ i ] += k ; }
8
12 13 14 15 16 17 18 19 20 21
DATENSTRUKTUREN
} / / Summe von a [ 0 ] b i s a [ i ] ( i n k l . ) i n t g e t ( v e c t o r & a , i n t i ) { int r = a [ 0 ] ; while (++ i < i n t ( a . s i z e ( ) ) ) { r −= a [ i ] ; i |= i − 1; } return r ; }
8.4 8.4.1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
Trie mit verketteter Liste
struct t r i e { s t r u c t t r i e ∗ next , ∗down ; char l e t t e r ; } node [ 1 0 0 0 0 0 0 ] ; / ∗ g g f . Anzahl anpassen ∗ / i n t nodes = 0 ; / ∗ so macht man a l l e T r i e s u n g u e l t i g ∗ / s t r u c t t r i e ∗ r o o t = NULL ; / ∗ so l o e s c h t man einen e i n z e l n e n T r i e ∗ / / ∗ A u f r u f m i t add(& r o o t , s t r ) ; g i b t t r u e zurueck , wenn Wort noch n i c h t vorhanden war ∗ / i n t add ( s t r u c t t r i e ∗∗ r o o t p p , char ∗word ) { s t r u c t t r i e ∗p , ∗∗ prev pp ; i n t n = nodes ; do { f o r ( prev pp = r o o t p p ; ( p = ∗ prev pp ) ! = NULL && p−>l e t t e r < ∗word ; prev pp = &(p−>n e x t ) ) {} i f ( p == NULL | | p−>l e t t e r ! = ∗word ) { p = node + nodes ++; p−>n e x t = ∗ prev pp ; p−>down = NULL ; p−>l e t t e r = ∗word ; ∗ prev pp = p ; } r o o t p p = &p−>down ; } while ( ∗ word + + ) ; r e t u r n n < nodes ; } / ∗ A u f r u f m i t check ( r o o t , s t r ) ; g i b t t r u e zurueck , wenn Wort vorhanden ∗ / i n t check ( s t r u c t t r i e ∗ r o o t , char ∗word ) { do { while ( r o o t ! = NULL && r o o t −>l e t t e r < ∗word ) r o o t = r o o t −>n e x t ; i f ( r o o t == NULL | | r o o t −>l e t t e r ! = ∗word ) r e t u r n 0 ; r o o t = r o o t −>down ; } while ( ∗ word + + ) ; return 1; }
8.4.2
2 3 4 5 6 7 8 9 10 11
Trie mit Array
1
Trie
1
31
# define ALPHA ’A ’ struct t r i e { s t r u c t t r i e ∗down [ 2 6 ] ; bool e n d o f w o r d ; } node [ 1 0 0 0 0 0 ] ; / / g g f . Anzahl anpassen i n t nodes = 0 ; / / so macht man a l l e T r i e s u n g u e l t i g s t r u c t t r i e ∗ r o o t = NULL ; / / so l o e s c h t man einen e i n z e l n e n T r i e / / A u f r u f m i t add(& r o o t , s t r ) ; g i b t t r u e zurueck , wenn Wort noch n i c h t vorhanden war bool add ( s t r u c t t r i e ∗∗ r o o t p t r , char ∗word ) { s t r u c t t r i e ∗p ; do {
8
DATENSTRUKTUREN
p = ∗root ptr ; i f ( p == NULL ) { p = node + nodes ++; f o r ( i n t i = 0 ; i < 2 6 ; ++ i ) p−>down [ i ] = NULL ; p−>e n d o f w o r d = f a l s e ; ∗root ptr = p; } r o o t p t r = p−>down + ( ∗ word − ALPHA ) ; } while ( ∗ word + + ) ; r e t u r n p−>e n d o f w o r d ? f a l s e : ( p−>e n d o f w o r d = t r u e ) ;
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
32
} / / A u f r u f m i t check ( r o o t , s t r ) ; g i b t t r u e zurueck , wenn Wort vorhanden bool check ( s t r u c t t r i e ∗ r o o t , char ∗word ) { while ( ∗ word ) { i f ( r o o t == NULL ) r e t u r n f a l s e ; r o o t = r o o t −>down [ ∗ word++ − ALPHA ] ; } r e t u r n r o o t ! = NULL && r o o t −>e n d o f w o r d ; }
8.5
¨ Balancierter binarer Suchbaum (AVL)
1 2 3 4
# include struct a v l t { a v l t ∗ l e f t , ∗ r i g h t , ∗up ; i n t h e i g h t , s i z e , key ;
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
void r e s e t ( ) ; i n t balance ( ) ; a v l t ∗ l e f t r o t ( ) ; a v l t ∗ r i g h t r o t ( ) ; a v l t ∗ f i x u p ( ) ; avl t ∗ latch ( avl t ∗ , avl t ∗); avl t ∗ find ( int ) ; a v l t ∗minimum ( ) ; a v l t ∗maximum ( ) ; a v l t ∗ pred ( ) ; a v l t ∗ succ ( ) ; }; i n l i n e void a v l t : : r e s e t ( ) { h e i g h t = max ( l e f t ! = NULL ? l e f t −>h e i g h t + 1 : 0 , r i g h t ! = NULL ? r i g h t −>h e i g h t + 1 : 0 ) ; s i z e = 1 + ( l e f t ! = NULL ? l e f t −>s i z e : 0 ) + ( r i g h t ! = NULL ? r i g h t −>s i z e : 0 ) ; } i n l i n e i n t a v l t : : balance ( ) { r e t u r n ( r i g h t ! = NULL ? r i g h t −>h e i g h t + 1 : 0 ) − ( l e f t ! = NULL ? l e f t −>h e i g h t + 1 : 0 ) ; } avl t ∗avl t :: leftrot () { a v l t ∗temp = r i g h t ; i f ( ( r i g h t = temp−> l e f t ) ! = NULL ) r i g h t −>up = t h i s ; temp−> l e f t = t h i s ; temp−>up = up ; up = temp ; r e s e t ( ) ; temp−>r e s e t ( ) ; r e t u r n temp ; } avl t ∗avl t :: rightrot () { a v l t ∗temp = l e f t ; i f ( ( l e f t = temp−>r i g h t ) ! = NULL ) l e f t −>up = t h i s ; temp−>r i g h t = t h i s ; temp−>up = up ; up = temp ; r e s e t ( ) ; temp−>r e s e t ( ) ; r e t u r n temp ; } avl t ∗ avl t : : fixup () { i n t b a l = balance ( ) ; i f ( b a l == 2 ) { i f ( r i g h t −>balance ( ) < 0 ) r i g h t = r i g h t −>r i g h t r o t ( ) ; return l e f t r o t ( ) ; } else i f ( b a l == −2) { i f ( l e f t −>balance ( ) > 0 ) l e f t = l e f t −> l e f t r o t ( ) ; return r i g h t r o t ( ) ; } return this ; } a v l t ∗ a v l t : : l a t c h ( a v l t ∗ root , a v l t ∗ parent ) {
8
44 45 46 47 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
33
i f ( r o o t == NULL ) { l e f t = r i g h t = NULL ; up = p a r e n t ; r e s e t ( ) ; r e t u r n t h i s ; } i f ( key < r o o t −>key ) r o o t −> l e f t = l a t c h ( r o o t −>l e f t , r o o t ) ; else i f ( r o o t −>key < key ) r o o t −>r i g h t = l a t c h ( r o o t −>r i g h t , r o o t ) ; r o o t −>r e s e t ( ) ; r e t u r n r o o t −>f i x u p ( ) ;
43
48
DATENSTRUKTUREN
} a v l t ∗ a v l t : : f i n d ( i n t value ) { a v l t ∗temp = t h i s ; while ( temp ! = NULL ) { i f ( v a l u e < temp−>key ) temp = temp−> l e f t ; else i f ( temp−>key < v a l u e ) temp = temp−>r i g h t ; else r e t u r n temp ; } r e t u r n NULL ; } a v l t ∗ a v l t : : minimum ( ) { a v l t ∗temp = t h i s ; while ( temp−> l e f t ! = NULL ) temp = temp−> l e f t ; r e t u r n temp ; } a v l t ∗ a v l t : : maximum ( ) { a v l t ∗temp = t h i s ; while ( temp−>r i g h t ! = NULL ) temp = temp−>r i g h t ; r e t u r n temp ; } a v l t ∗ a v l t : : pred ( ) { a v l t ∗temp = t h i s ; i f ( l e f t ! = NULL ) r e t u r n l e f t −>maximum ( ) ; while ( temp−>up ! = NULL && temp == temp−>up−> l e f t ) temp = temp−>up ; r e t u r n temp−>up ; } a v l t ∗ a v l t : : succ ( ) { a v l t ∗temp = t h i s ; i f ( r i g h t ! = NULL ) r e t u r n r i g h t −>minimum ( ) ; while ( temp−>up ! = NULL && temp == temp−>up−>r i g h t ) temp = temp−>up ; r e t u r n temp−>up ; }