Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » 1. Mönchs-rätsel

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
13.06.2003, 08:36 Uhr
Bruder Leif
dances with systems
(Operator)


Der Quicksort-Algorithmus teilt bekanntlich das zu sortierende Array in zwei Teile auf, die dann rekursiv weiterverarbeitet werden. Besonders effektiv arbeiten wir, wenn beide Teilbereiche möglichst gleich groß sind, d.h. wenn als mittleres (Trenn-)Element ein Wert gewählt wird, der nach dem Sortieren in der Mitte des Bereichs liegt. Diesen Wert bezeichnet man als Median. Normalerweise nimmt sich Quicksort den Wert in der Mitte des noch unsortierten Bereichs, bei nicht vorsortierten Arrays auch mal den ersten oder letzten Eintrag. Optimal ist das aber nicht ;-)

Gesucht ist jetzt ein Algorithmus, der in einem unsortierten int-Array möglichst schnell den Median (bzw. seine Position im Array) auffindet, damit Quicksort ein wenig verbessert werden kann ;-)
Tip: Es gibt ja noch andere Sortierverfahren, und manche davon geben nach ein paar "Anpassungen" eine brauchbare Lösung ab...
--
Mit 40 Fieber sitzt man nicht mehr vor dem PC.
Man liegt im Bett.
Mit dem Notebook.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.06.2003, 09:49 Uhr
~0xdeadbeef
Gast


Das hier ist O(n):

C++:
#include <math.h>

int find_median_index(int [] arr, int len) {
    int i, med_ix = 0, sum_n = 0;
    double med = 0.0L;

    for(i = 0; i < len; ++i) {
        med + =((double) ((i+1)*arr[i]-sum_n))/((i+1)*(i+2));
        sum_n += arr[i];
        if(fabs(arr[i] - med) < fabs(arr[med_ix] - med)) med_ix = i;
    }

    return med_ix;
}


Das basiert darauf, dass du vom Median der ersten n Werte auf den Median der ersten n+1 Werte schließen kannst, indem du

1. Auf den Hauptnenner erweiterst, um in LaTeX zu sprechen:

Code:
\frac{\sum_{i=1}^n a_i}{n} = \frac{(n+1)\sum_{i=1}^n a_i}{n(n+1)}


2. Den Zähler hernimmst, das macht die Sache einfacher. Dann einmal die Summe von a_1 bis a_n abziehen und n*(a_{n+1}) draufrechnen:

Code:
(n+1) \sum_{i=1}^n a_i - \sum_{i=1}^n a_i + na_{n+1} = n \sum_{i=1}^{n+1}a_i


Im Endeffekt kriegst du

Code:
\frac{n\sum_{i=1}^{n+1}a_i}{n(n+1)} = \frac{\sum_{i=1}^{n+1} a_i}{n+1}


und das wollten wir ja haben. Also musst du bei jedem Iterationsschritt folgendes auf den Median draufaddieren:

Code:
\frac{na_{n+1} - \sum_{i=1}^n a_i}{n(n+1)}


und weil wir in C 0-basierte Arrays haben, sieht das in Code so aus:

C++:
        med + =((double) ((i+1)*arr[i]-sum_n))/((i+1)*(i+2));


Kleinere Tipfeeler bitte ich zu entschuldigen, es geht mir um das grundsätzliche Rechenprinzip.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.06.2003, 17:05 Uhr
Tommix



Hallo,
sowas ähnliches in anderem Kontext hatten wir schon mal: Mein Median-Problem 2001.
Fand die Diskussion hochinteressant damals.

Gruss, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: