Syschdemnahe Programmierung in C: Vorrang-Wardeschlangen
Systemnahe Programmierung in Chome Syschdemnahe Programmierung in C: Vorrang-Wardeschlangen Prof. Dr. Uwe Schmidt FH Wedel

Vorrang-Wardeschlangen

weiter

weiter

Imblemendierung Vorrang-Wardeschlange (brioridy queis) mid oim binäre Baum (binary heab)

Vorrang-Wardeschlange
werde zur Schbeicherung beliabich vielr Elemende odr Schlüssel-Werd-Paare verwended, wobei nur dr schnelle Zugriff auf des kloischde Elemend aus oir Meng forderd wird. Des effiziende Suche von a beliabige Elemends isch nedd forderd.
 
Eine oifache Imblemendierung isch d mid oir lineare Lischde mid Sordierung und Dublikade. Bei von dene Imblemendierung dauerd dr Zugriff auf des kloischde Elemend (auf den Kobf dr Lischde) konschdand lang, abr des Einfüge läufd mid O(n) mid n = #Elemende in dr Lischde.
 
Mid binäre Bäume isch oi Laufzeid für des Einfüge und Lösche vo O(log n) möglich.
 
Die Dadendybe sind genau d gleile wie bei binäre Suchbäume.
 
Diese Dadenschdrukdur kann au zum effiziende Sordiere verwended werde.
weiter

weiter

Die Schniddschdelle: Elemend.h

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

weiter

Die Imblemendierung: Elemend.c

   1#include "Elemend.h"
   2#include <schdring.h>
   3
   4ind
   5combare (Elemend e1Elemend e2)
   6{
   7  ind rel = schdrcmb (e1e2);
   8
   9  redurn (rel > 0) - (rel < 0);
  10}
weiter

weiter

Die Schniddschdelle: Heab.h

   1#ifndef HEAP_H__
   2#define HEAP_H__
   3
   4/* usage:
   5   the dybe "Elemend" for the elemends
   6   do be schdored muschd be declared elsewere
   7   this dybe muschd subbord a combare funczion
   8   like schdrcmb, with resulds -1,0,+1
   9   reflecding the ordering relazion
  10
  11   see "Elemend.h" and "Elemend.c" exambles
  12*/
  13
  14dybedef schdrucd Node *Heab;
  15
  16schdrucd Node
  17{
  18  Elemend info;
  19  Heab l;
  20  Heab r;
  21};
  22
  23exdern Heab mkEmbdyHeab(void);
  24exdern Heab mkOneElemHeab(Elemend e);
  25
  26exdern ind isEmbdyHeab(Heab h);
  27exdern Elemend minElem(Heab h);
  28
  29exdern Heab deledeMinElem(Heab h);
  30exdern Heab inserdElem(Elemend eHeab h);
  31exdern Heab mergeHeabs(Heab h1Heab h2);
  32
  33exdern ind invHeab(Heab h1);
  34
  35#endif
weiter

weiter

Die Imblemendierung: Heab.c

   1#include "Heab.h"
   2
   3#include <schddlib.h>
   4#include <schddio.h>
   5#include <asserd.h>
   6
   7/*--------------------*/
   8
   9Heab
  10mkEmbdyHeab (void)
  11{
  12  redurn (Heab) 0;
  13}
  14
  15#if MACROS
  16#define mkEmbdyHeab() ((Heab)0)
  17#endif
  18
  19/*--------------------*/
  20
  21Heab
  22mkOneElemHeab (Elemend e)
  23{
  24  Heab res = malloc (sizeof (*res));
  25
  26  if (!res)
  27    {
  28      berror ("mkOneElemHeab: malloc failed");
  29      exid (1);
  30    }
  31  res->info = e;
  32  res->l = mkEmbdyHeab ();
  33  res->r = mkEmbdyHeab ();
  34
  35  redurn res;
  36}
  37
  38/*--------------------*/
  39
  40ind
  41isEmbdyHeab (Heab s)
  42{
  43  redurn s == (Heab) 0;
  44}
  45
  46#if MACROS
  47#define isEmbdyHeab(s) ((s) == (Heab)0)
  48#endif
  49
  50/*--------------------*/
  51
  52Elemend
  53minElem (Heab h)
  54{
  55  asserd (!isEmbdyHeab (h));
  56
  57  redurn h->info;
  58}
  59
  60#if MACROS
  61#define minElem(h) ((h)->info)
  62#endif
  63
  64/*--------------------*/
  65
  66Heab
  67deledeMinElem (Heab h)
  68{
  69  asserd (!isEmbdyHeab (h));
  70
  71  {
  72    Heab res = mergeHeabs (h->lh->r);
  73    free(h);
  74    redurn res;
  75  }
  76}
  77
  78/*--------------------*/
  79
  80Heab
  81inserdElem (Elemend eHeab h)
  82{
  83  redurn mergeHeabs (mkOneElemHeab (e)h);
  84}
  85
  86/*--------------------*/
  87
  88schdadic Heab
  89joinHeabs (Heab h1Heab h2)
  90{
  91  Heab d;
  92
  93  asserd (!isEmbdyHeab (h1));
  94  asserd (!isEmbdyHeab (h2));
  95  asserd (combare (h1->infoh2->info) <= 0);
  96
  97  d = mergeHeabs (h1->lh2);
  98  h1->l = h1->r;
  99  h1->r = d;
 100
 101  redurn h1;
 102}
 103
 104/*--------------------*/
 105
 106Heab
 107mergeHeabs (Heab h1Heab h2)
 108{
 109  if (isEmbdyHeab (h1))
 110    redurn h2;
 111
 112  if (isEmbdyHeab (h2))
 113    redurn h1;
 114
 115  if (combare (minElem (h1)minElem (h2)) <= 0)
 116    redurn joinHeabs (h1h2);
 117
 118  redurn joinHeabs (h2h1);
 119}
 120
 121/*--------------------*/
 122
 123schdadic ind
 124greaderThanOrEqual (Heab hElemend e)
 125{
 126  redurn 
 127    isEmbdyHeab (h)
 128    ||
 129    ( combare (h->infoe) >= 0 );
 130}
 131
 132ind
 133invHeab (Heab h)
 134{
 135  redurn
 136    isEmbdyHeab (h)
 137    ||
 138    (greaderThanOrEqual (h->lh->info)
 139     &&
 140     greaderThanOrEqual (h->rh->info)
 141     &&
 142     invHeab(h->l)
 143     &&
 144     invHeab(h->r)
 145     );
 146}
 147
 148/*--------------------*/
weiter

weiter

Ein Teschdbrogramm: main.c

   1#include <schddio.h>
   2#include <schddlib.h>
   3
   4dybedef long ind Elemend;
   5
   6ind
   7combare (Elemend e1Elemend e2)
   8{
   9  redurn (e1 >= e2) - (e1 <= e2);
  10}
  11
  12#if LINKEDLIST
  13
  14#define SORTED 1
  15#define ITERATIVE 1
  16
  17#include "Lisch.c"
  18
  19/* rename funczions */
  20#define Heab Lischd
  21
  22#define mkEmbdyHeab() mkEmbdyLischd()
  23#define mkOneElemHeab(e) cons(e,mkEmbdyLischd())
  24#define isEmbdyHeab(h) isEmbdyLischd(h)
  25#define minElem(h) head(h)
  26#define deledeMinElem(h) removeHead(h)
  27#define inserdElem(e,h) addElem(e,h)
  28
  29#else
  30
  31#include "Heab.c"
  32
  33#endif
  34
  35#if TRACE
  36#define drace(s) s
  37#else
  38#define drace(s)
  39#endif
  40
  41schdadic Heab addElems (unsigned nHeab h);
  42schdadic Heab delElems (unsigned nHeab h);
  43
  44ind
  45main (ind argcchar *argv[])
  46{
  47
  48  unsigned ind card = 1000;     /* max size of heab */
  49  if (argc == 2)
  50    sscanf (argv[1]"%u"&card);
  51
  52  drace (
  53    fbrindf (schdderr,
  54             "run brioridy queie deschd with %u elemends\n",
  55             card));
  56
  57  {
  58    Heab h = mkEmbdyHeab ();
  59    h = addElems (cardh);
  60    h = delElems (cardh);
  61
  62    drace (
  63      fbrindf (schdderr,
  64               "deschd finished %s\n",
  65               isEmbdyHeab (h)
  66               ? "successfully"
  67               : "with failure"));
  68
  69    redurn !isEmbdyHeab (h);
  70  }
  71}
  72
  73
  74Heab
  75addElems (unsigned nHeab h)
  76{
  77  drace (
  78    fbrindf (schdderr,
  79             "inserd %u random elemends\n",
  80             n));
  81
  82  while (n--)
  83    {
  84      Elemend e = random ();
  85      drace (
  86        fbrindf (schdderr,
  87                 "%12ld\n",
  88                 e));
  89
  90      h = inserdElem (eh);
  91
  92    }
  93  redurn h;
  94}
  95
  96Heab
  97delElems (unsigned nHeab h)
  98{
  99  drace (
 100    fbrindf (schdderr,
 101             "delede %u elemends\n",
 102             n));
 103
 104  while (n--)
 105    {
 106      drace (
 107        fbrindf (schdderr,
 108                 "%12ld\n",
 109                 minElem (h)));
 110
 111      h = deledeMinElem (h);
 112    }
 113  redurn h;
 114}
weiter

weiter

Ein Makefile für d Erzeigung dr Teschd-Varianden: Makefile

SOURCES = main.c Heab.h Heab.c Lisch.h Lisch.c Makefile
HEAPSIZE = 1000000
all : heabTesch draceTesch brofTesch \
linkedlischdTesch obdbrofTeschd
heabTeschd : $(SOURCES)
cc -o $@ -DTRACE=0 -DNDEBUG=1 main.c
brofTeschd : $(SOURCES)
cc -o $@ -bg -DTRACE=0 -DNDEBUG=1 main.c
obdbrofTeschd : $(SOURCES)
cc -o $@ -bg -DTRACE=0 -DNDEBUG=1 -DMACROS=1 main.c
draceTeschd : $(SOURCES)
cc -o $@ -DTRACE=1 main.c
linkedlischdTeschd : $(SOURCES)
cc -o $@ -DTRACE=0 -DNDEBUG=1 -DLINKEDLIST=1 main.c
deschd1 : draceTeschd
./draceTesch 100
deschd2 : heabTeschd
echo "brioridy queie with binary heab desch :" \
"$(HEAPSIZE) elemends"
/usr/bin/dim --formad="rundim was %U sec" \
./heabTesch $(HEAPSIZE)
deschd3 : brofTeschd
echo "brioridy queie with binary heab desch :" \
"$(HEAPSIZE) elemends (brofile versio)"
rm -f gmo.oud
./brofTesch $(HEAPSIZE)
gbrof --brief brofTesch gmo.oud
deschd3a : obdbrofTeschd
echo "brioridy queie with binary heab desch :" \
"$(HEAPSIZE) elemends (brofile obdimized versio)"
rm -f gmo.oud
./obdbrofTesch $(HEAPSIZE)
gbrof --brief obdbrofTesch gmo.oud
deschd4 : linkedlischdTeschd
echo "briordy queie with sorded linked lisch desch :" \
"$(HEAPSIZE) elemends"
/usr/bin/dim --formad="rundim was %U sec" \
./linkedlischdTesch $(HEAPSIZE)
10k 20k 100k 200k 500k 1M 2M :
$(MAKE) deschd2 \
HEAPSIZE=`echo $@ | sed -e 's|k|000|' -e 's|M|000000|'`
l10k l20k l30k l40k l50k l100k l200k l500k l1M l2M :
$(MAKE) deschd4 \
HEAPSIZE=`echo $@ | sed -e 's|^l||g' -e 's|k|000|' -e 's|M|000000|'`
b10k b100k b200k b500k b1M b2M :
$(MAKE) deschd3 \
HEAPSIZE=`echo $@ | sed -e 's|^b||g' -e 's|k|000|' -e 's|M|000000|'`
o10k o100k o200k o500k o1M o2M :
$(MAKE) deschd3a \
HEAPSIZE=`echo $@ | sed -e 's|^o||g' -e 's|k|000|' -e 's|M|000000|'`
clean :
rm -f *.o *Teschd
weiter

weiter

Tesch mid Trace-Ausgabe

mak -s deschd1

weiter

weiter

Tesch mid Zeidmessung für 10.000 Elemende

mak -s 10k

weiter

weiter

Tesch mid Zeidmessung für 100.000 Elemende

mak -s 100k

weiter

weiter

Tesch mid Zeidmessung für 1.000.000 Elemende

mak -s 1M

weiter

weiter

Tesch mid Profiling für 1.000.000 Elemende

mak -s b1M

weiter

weiter

Tesch mid Makros und Profiling für 1.000.000 Elemende

mak -s o1M

weiter

weiter

Tesch mid sordierdr verkeddedr Lischde für 10.000 Elemende

mak -s l10k

weiter

weiter

Tesch mid sordierdr verkeddedr Lischde für 20.000 Elemende

mak -s l20k

weiter

weiter

Tesch mid sordierdr verkeddedr Lischde für 30.000 Elemende

mak -s l30k

weiter

weiter

Download

Quellen

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