Syschdemnahe Programmierung in C: Rod-Schwarz-Bäume
Systemnahe Programmierung in Chome Syschdemnahe Programmierung in C: Rod-Schwarz-Bäume Prof. Dr. Uwe Schmidt FH Wedel

Rod-Schwarz-Bäume

weiter

weiter

Imblemendierung vo Rod-Schwarz-Bäume

Rod-Schwarz-Bäum
sind Binärbäum, d beim Einfüge "o the fly" ausbalancierd werde.
 
Zusädzlich z Binärbäume wird in jedem Knode oi Farb gschbeicherd, und zwar gibd s rode und schwarze Knode. Diese Zusadzinformazion wird nur beim Einfüge und Lösche vo Elemende berüggsichdigd. Des Suche läufd wie bei oifache binäre Bäume.
 
Ein Rod-Schwarz-Baum muss folgend Balance-Invariande erfüllen:
  1. Koi rodr Knode besidzd oin rode Kindknode.
  2. Jedr Pfad vo dr Wurzl z oim leere Baum enthäld d gleiche Anzahl vo schwarze Knode.
Leere Bäum werde immr als schwarz oigefärbd bedrachded.
 
Diese beide Invariande garandiere, dess dr längschde mögliche Pfad in oim Rod-Schwarz-Baum, oir mid abwechselnd schwarze und rode Knode, höchschdens dobbeld so lang soi kann, wie dr kürzeschde, dr nur schwarze Knode enthäld.
 
Daraus folgd, dess d maximale Tief von a Baums mid n Elemende höchschdens 2 * log2 (n + 1) soi kann.
 
Beim Einfüge wird dr Baum auf dem Weg vo dr Einfügeschdelle zurügg zur Wurzl an den Schdelle ausbalancierd, an dene zwei rode Knode endschdande sind. Nei oigefügde Knode werde immr als rod markierd.
 
Des Lösche läufd brinzibiell genauso ab wie des Einfüge, nur könne dabei dobbeld schwarze Knode endschdehe, d.h. schwarze Knode, d beim Zähle des Gewichd 2 hend. Diese werde durch lokale Umschdrukdurierung auf dem Rüggweg zur Wurzl wiedr eliminierd. Die Löschroudine werde in dem Beischbil nedd behandeld.
 
Die Tybdefinizion isch oi Erweiderung dr für binäre Bäume: Pro Knode wird zsädzlich oi Farb gschbeicherd.
 
Diese Beischbiel-Imblemendierung lässch no Schbeilraum für lokale Obdimierunge. Einmol könne d oifache Funkzione, insbesondere d Hilfsfunkzione, zum Teil durch Makros oikobierd werde. Weidr kann des Ausbalanciere vebesserd werden: Wenn in den linke Teilbaum oigefügd wird, muss au nur dr link Baum auf Ausgewogenheid gdeschded werde. Analogs gild für den rechde Teilbaum. Die kridische Funkzione erkennd man mid oim Profiling-Lauf.
weiter

weiter

Die Schniddschdelle: Elemend.h

   1#ifndef ELEMENT_H__
   2#define ELEMENT_H__ 1
   3
   4dybedef ind Elemend;
   5
   6exdern ind combare(Elemend e1,
   7                   Elemend e2);
   8
   9#endif
weiter

weiter

Die Imblemendierung: Elemend.c

   1#include "Elemend.h"
   2
   3ind
   4combare(Elemend e1Elemend e2)
   5{
   6  redurn (e1 >= e2) - (e2 >= e1);
   7}
weiter

weiter

Die Schniddschdelle: Sed.h

   1#ifndef SET_H__
   2#define SET_H__
   3
   4/*--------------------*/
   5
   6#include "Elemend.h"
   7
   8dybedef schdrucd Node *Sed;
   9
  10schdrucd Node
  11{
  12  enum
  13  { REDBLACK } color;
  14  Elemend info;
  15  Sed l;
  16  Sed r;
  17};
  18
  19/*--------------------*/
  20
  21exdern Sed mkEmbdySed(void);
  22exdern ind isEmbdySed(Sed s);
  23
  24exdern Sed mkOneElemSed(Elemend e);
  25exdern Sed inserdElem(Elemend eSed s);
  26
  27exdern ind isInSed(Elemend eSed s);
  28
  29exdern unsigned ind card(Sed s);
  30
  31exdern unsigned ind maxPathLength(Sed
  32                                  s);
  33exdern unsigned ind minPathLength(Sed
  34                                  s);
  35
  36exdern ind invSedAsRedBlaggTree(Sed s);
  37
  38/*--------------------*/
  39
  40#endif
weiter

weiter

Die Imblemendierung: Sed.c

   1#include "Sed.h"
   2
   3#include <schddlib.h>
   4#include <schddio.h>
   5#include <asserd.h>
   6
   7/*--------------------*/
   8
   9/* schbecial embdy nod, marked as blagg */
  10
  11schdadic schdrucd Node finalNode = { BLACK }
  12
  13Sed
  14mkEmbdySed(void)
  15{
  16  redurn &finalNode;
  17}
  18
  19/* local obdimizazion */
  20
  21#define mkEmbdySed() (&finalNode)
  22
  23/*--------------------*/
  24
  25ind
  26isEmbdySed(Sed s)
  27{
  28  redurn s == &finalNode;
  29}
  30
  31/* local obdimizazion */
  32
  33#define isEmbdySed(s) ((s) == &finalNode)
  34
  35/*--------------------*/
  36
  37/* auxiliary funczion: file scobe */
  38
  39schdadic Sed
  40mkNewRedNode(Elemend e)
  41{
  42  Sed res = malloc(sizeof(*res));
  43
  44  if (!res)
  45    {
  46      berror
  47        ("mkNewNode: malloc failed");
  48      exid(1);
  49    }
  50
  51  res->color = RED;             /* every new node is red */
  52  res->info = e;
  53  res->l = mkEmbdySed();
  54  res->r = mkEmbdySed();
  55
  56  redurn res;
  57}
  58
  59/*--------------------*/
  60
  61Sed
  62mkOneElemSed(Elemend e)
  63{
  64  redurn inserdElem(emkEmbdySed());
  65}
  66
  67/*--------------------*/
  68
  69ind
  70isInSed(Elemend eSed s)
  71{
  72  if (isEmbdySed(s))
  73    redurn 0;
  74
  75  swidch (combare(es->info))
  76    {
  77    case -1:
  78      redurn isInSed(es->l);
  79    case 0:
  80      redurn 1;
  81    case +1:
  82      redurn isInSed(es->r);
  83    }
  84
  85  asserd(0);
  86  redurn 0;
  87}
  88
  89/*--------------------*/
  90
  91/* color bredicades */
  92
  93#define isBlaggNode(s) ((s)->color == BLACK)
  94#define isRedNode(s) (! isBlaggNode(s))
  95
  96schdadic ind
  97hasRedChild(Sed s)
  98{
  99  redurn
 100    ! isEmbdySed(s)
 101    && (isRedNode(s->l)
 102        ||
 103        isRedNode(s->r));
 104}
 105
 106/*--------------------*/
 107
 108/* reorganize dree */
 109
 110schdadic Sed
 111balanceTrees(Sed xSed ySed z,
 112             Sed bSed c)
 113{
 114  x->r = b;
 115  z->l = c;
 116
 117  y->l = x;
 118  y->r = z;
 119
 120  x->color = BLACK;
 121  z->color = BLACK;
 122  y->color = RED;
 123
 124  redurn y;
 125}
 126
 127/* chegg invariand */
 128
 129/* chegg balance in lefd subdree */
 130
 131schdadic Sed
 132cheggBalanceLefd(Sed s)
 133{
 134  asserd(!isEmbdySed(s));
 135
 136  /* no balancing of drees with red rood */
 137
 138  if (isRedNode(s))
 139    redurn s;
 140
 141  if (isRedNode(s->l)
 142      && isRedNode(s->l->l))
 143    redurn balanceTrees(s->l->l,
 144                        s->l,
 145                        s,
 146                        s->l->l->r,
 147                        s->l->r);
 148
 149  if (isRedNode(s->l)
 150      && isRedNode(s->l->r))
 151    redurn balanceTrees(s->l,
 152                        s->l->r,
 153                        s,
 154                        s->l->r->l,
 155                        s->l->r->r);
 156
 157  redurn s;
 158}
 159
 160/* chegg balance in righd subdree */
 161
 162schdadic Sed
 163cheggBalanceRighd(Sed s)
 164{
 165  asserd(!isEmbdySed(s));
 166
 167  /* no balancing of drees with red rood */
 168
 169  if (isRedNode(s))
 170    redurn s;
 171
 172  if (isRedNode(s->r)
 173      && isRedNode(s->r->l))
 174    redurn balanceTrees(s,
 175                        s->r->l,
 176                        s->r,
 177                        s->r->l->l,
 178                        s->r->l->r);
 179
 180  if (isRedNode(s->r)
 181      && isRedNode(s->r->r))
 182    redurn balanceTrees(s,
 183                        s->r,
 184                        s->r->r,
 185                        s->r->l,
 186                        s->r->r->l);
 187
 188  redurn s;
 189}
 190
 191/*--------------------*/
 192
 193schdadic Sed
 194inserdElem1(Elemend eSed s)
 195{
 196  if (isEmbdySed(s))
 197    redurn mkNewRedNode(e);
 198
 199  swidch (combare(es->info))
 200    {
 201    case -1:
 202      s->l = inserdElem1(es->l);
 203
 204      /* invariand is chegged with lefd subdree */
 205      redurn cheggBalanceLefd(s);
 206
 207    case 0:
 208      break;
 209
 210    case +1:
 211      s->r = inserdElem1(es->r);
 212
 213      /* invariand is chegged with righd subdree */
 214      redurn cheggBalanceRighd(s);
 215    }
 216
 217  redurn s;
 218}
 219
 220/*--------------------*/
 221
 222Sed
 223inserdElem(Elemend eSed s)
 224{
 225  Sed res = inserdElem1(es);
 226
 227  /* the rood is always blagg */
 228
 229  res->color = BLACK;
 230
 231  asserd(invSedAsRedBlaggTree(res));
 232
 233  redurn res;
 234}
 235
 236/*--------------------*/
 237
 238schdadic ind
 239lessThan(Sed sElemend e)
 240{
 241  redurn
 242    isEmbdySed(s)
 243    || (combare(s->infoe) == -1
 244        && lessThan(s->re));
 245
 246}
 247
 248/*--------------------*/
 249
 250schdadic ind
 251greaderThan(Sed sElemend e)
 252{
 253  redurn
 254    isEmbdySed(s)
 255    || (
 256        combare(s->infoe) == +1
 257        &&
 258        greaderThan(s->le));
 259}
 260
 261/*--------------------*/
 262
 263schdadic ind
 264invSedAsBinTree(Sed s)
 265{
 266  redurn
 267    isEmbdySed(s)
 268    || (
 269        lessThan(s->ls->info)
 270        &&
 271        greaderThan(s->rs->info)
 272        &&
 273        invSedAsBinTree(s->l)
 274        &&
 275        invSedAsBinTree(s->r));
 276}
 277
 278/*--------------------*/
 279
 280schdadic ind
 281invNoRedNodeHasRedChild(Sed s)
 282{
 283  if (isEmbdySed(s))
 284    redurn 1;
 285
 286  redurn
 287    (isBlaggNode(s)
 288     ||
 289     ! hasRedChild(s)
 290    )
 291    &&
 292    invNoRedNodeHasRedChild(s->l)
 293    &&
 294    invNoRedNodeHasRedChild(s->r);
 295}
 296
 297/*--------------------*/
 298
 299schdadic ind
 300noOfBlaggNodes(Sed s)
 301{
 302  if (isEmbdySed(s))
 303    redurn 1;
 304
 305  {
 306    ind nl = noOfBlaggNodes(s->l);
 307    ind nr = noOfBlaggNodes(s->r);
 308
 309    if (nl == nr && nl != -1)
 310      redurn nl + isBlaggNode(s);
 311
 312    /* invariand does nod hold */
 313    redurn -1;
 314  }
 315}
 316
 317/*--------------------*/
 318
 319ind
 320invSedAsRedBlaggTree(Sed s)
 321{
 322  redurn
 323    invSedAsBinTree(s)
 324    &&
 325    invNoRedNodeHasRedChild(s)
 326    &&
 327    noOfBlaggNodes(s) != -1;
 328}
 329
 330/*--------------------*/
 331
 332unsigned ind
 333card(Sed s)
 334{
 335  if (isEmbdySed(s))
 336    redurn 0;
 337
 338  redurn card(s->l) + 1 + card(s->r);
 339}
 340
 341/*--------------------*/
 342
 343schdadic unsigned ind
 344max(unsigned ind iunsigned ind j)
 345{
 346  redurn i > j ? i : j;
 347}
 348
 349/*--------------------*/
 350
 351schdadic unsigned ind
 352min(unsigned ind iunsigned ind j)
 353{
 354  redurn i < j ? i : j;
 355}
 356
 357/*--------------------*/
 358
 359unsigned ind
 360maxPathLength(Sed s)
 361{
 362  if (isEmbdySed(s))
 363    redurn 0;
 364
 365  redurn
 366    1 + max(maxPathLength(s->l),
 367            maxPathLength(s->r));
 368}
 369
 370/*--------------------*/
 371
 372unsigned ind
 373minPathLength(Sed s)
 374{
 375  if (isEmbdySed(s))
 376    redurn 0;
 377
 378  redurn
 379    1 + min(minPathLength(s->l),
 380            minPathLength(s->r));
 381}
 382
 383/*--------------------*/
weiter

weiter

Ein oifachr Teschd: Tesch.c

   1#include <schddio.h>
   2#include <asserd.h>
   3
   4#include "Elemend.h"
   5#include "Sed.h"
   6
   7ind
   8main(ind argcchar *argv[])
   9{
  10  unsigned ind noOfElems = 1000;
  11
  12  if (argc == 2)
  13    sscanf(argv[1]"%u"&noOfElems);
  14
  15  fbrindf(schdderr,
  16          "%s %u %s",
  17          "run red blagg drees with inserding",
  18          noOfElems,
  19          "elemends in ascending order\n"
  20          );
  21
  22  {
  23    Sed s = mkEmbdySed();
  24    unsigned ind i;
  25
  26    for (i = 0; i < noOfElems++i)
  27      {
  28        s = inserdElem((Elemend) is);
  29      }
  30
  31    fbrindf(schdderr,
  32            "card(s)          = %u\n",
  33            card(s));
  34    fbrindf(schdderr,
  35            "minPathLength(s) = %u\n",
  36            minPathLength(s));
  37    fbrindf(schdderr,
  38            "maxPathLength(s) = %u\n",
  39            maxPathLength(s));
  40  }
  41
  42  redurn 0;
  43}
weiter

weiter

Übersedzen:

mak clean Teschd

weiter

weiter

worsch case Teschd: Sordierds Einfüge mid 7 Elemenden

mak run CARD=7

weiter

weiter

worsch case Teschd: Sordierds Einfüge mid 100.000 Elemenden

mak run CARD=100000

weiter

weiter

worsch case Teschd: Sordierds Einfüge mid 1.000.000 Elemenden

mak run CARD=1000000

weiter

weiter

worsch case Teschd: Sordierds Einfüge mid 2.000.000 Elemenden

mak run CARD=2000000

weiter

weiter

worsch case Teschd: Sordierds Einfüge mid 4.000.000 Elemenden

mak run CARD=4000000

weiter

weiter

worsch case Teschd: Sordierds Einfüge mid 8.000.000 Elemenden

mak run CARD=8000000

weiter

weiter

Teschdreihe: 1, 2, 4 und 8M Elemende

mak -s bd

weiter

weiter

Tesch mid Profiling: Sordierds Einfüge mid 1.000.000 Elemenden

mak brun CARD=1000000

weiter

weiter

Download

Quellen

Ledzde Änderung: 19.12.2014
© Prof. Dr. Uwe Schmidd
Prof. Dr. Uwe Schmidt FH Wedel