Kihagyás

3.9. Rendezés

A programozás során az egyik leggyakoribb feladat az adatok valamilyen szempont szerinti sorba rendezése. Legyen szó egy webáruház termékeinek ár szerinti listázásáról, vagy a diákok névsorba szedéséről, a háttérben mindig valamilyen rendezési algoritmus fut.

A rendezés történhet növekvő (kicsitől a nagy felé) vagy csökkenő (nagytól a kicsi felé) sorrendben. Karakterek és szövegek esetén ez az ABC sorrendet jelenti.

A legfontosabb alaplépés: A változók értékének felcserélése

Mielőtt bármilyen tömböt sorba rendeznénk, meg kell oldanunk egy alapvető problémát: hogyan cseréljük meg két változó értékét?

Képzeld el, hogy van két poharad. Az egyikben (A pohár) narancslé van, a másikban (B pohár) kóla. Szeretnéd kicserélni a tartalmukat úgy, hogy az A-ban legyen a kóla, a B-ben a narancslé. Ha egyszerűen átöntöd az egyiket a másikba, a két folyadék összekeveredik. Szükséged van egy harmadik, üres pohárra (egy segédváltozóra)!

Poharas csere ábra - IDE ILLESZD BE A KÉPET

(A fenti ábrán látható a csere folyamata lépésről lépésre)

A programozásban a csere pontosan így működik. Létrehozunk egy seged változót, és ezen keresztül hajtjuk végre a cserét három lépésben:

int seged = a; // 1. lépés: Az 'A' tartalmát átöntjük az üres 'seged' pohárba
a = b;         // 2. lépés: A 'B' tartalmát átöntjük az immár üres 'A' pohárba
b = seged;     // 3. lépés: A 'seged' pohárból (ami eredetileg az 'A' volt) áttöltjük az anyagot a 'B'-be

Most, hogy tudunk cserélni, nézzük meg a két legismertebb alap-algoritmust a rendezésre!


3.9.1. Egyszerű cserés rendezés

Ez a legkönnyebben megérthető algoritmus. A lényege: fogjuk a tömb legelső elemét, és összehasonlítjuk az összes mögötte lévő elemmel. Ha találunk nála kisebbet (növekvő rendezés esetén), akkor azonnal kicseréljük őket. Mire a vizsgálat végére érünk, garantáltan a legkisebb elem kerül a tömb legelső helyére. Ezután fogjuk a második elemet, és azt is összehasonlítjuk az összes mögötte lévővel. Ezt addig ismételjük, amíg el nem érünk a tömb végéig.

A logikához két egymásba ágyazott for ciklus kell: * A külső ciklus (i) mondja meg, hogy épp melyik helyre keressük a megfelelő elemet. * A belső ciklus (j) mindig az i utáni elemtől indul (j = i + 1), és végigmegy a maradékon, hogy összehasonlítsa őket az i-edik elemmel.

31. feladat

Állítsunk elő véletlenszerűen 10 egész számot a [0, 100] tartományból! Írjuk ki a generált számokat, majd rendezzük őket növekvő sorrendbe egyszerű cserés rendezéssel, és írjuk ki a rendezett tömböt is! Név: Egyszerű cserés rendezés

Megoldás:

static void Main(string[] args)
{
    int[] a = new int[10];
    Random vsz = new Random();

    Console.WriteLine(" Az eredeti (rendezetlen) számok:");
    for (int i = 0; i < 10; i++)
    {
        a[i] = vsz.Next(101);
        Console.Write("{0,4}", a[i]);
    }
    Console.WriteLine("\n"); // Sortörés és egy üres sor

    // --- EGYSZERŰ CSERÉS RENDEZÉS ALGORITMUSA ---
    for (int i = 0; i < 10 - 1; i++) // A külső ciklus az utolsó előtti elemig megy
    {
        for (int j = i + 1; j < 10; j++) // A belső ciklus az i utáni elemtől indul
        {
            if (a[i] > a[j]) // Ha a bal oldali nagyobb, mint a jobb oldali, akkor cserélünk
            {
                int seged = a[i];
                a[i] = a[j];
                a[j] = seged;
            }
        }
    }

    Console.WriteLine(" A rendezett számok (növekvő):");
    for (int i = 0; i < 10; i++)
    {
        Console.Write("{0,4}", a[i]);
    }

    Console.ReadKey();
}


3.9.2. Minimumkiválasztásos rendezés

Az egyszerű cserés rendezés bár könnyen érthető, nagyon lassú tud lenni. Miért? Mert ahogy halad végig a belső ciklus, lehet, hogy ötször is végrehajtja a "poharas cserét", mire megtalálja az abszolút legkisebbet. A számítógép számára a memória írása (a változók cseréje) "drága" művelet.

A minimumkiválasztásos rendezés felokosítja ezt a folyamatot! Ahelyett, hogy azonnal cserélne, csak megjegyzi, hogy hányadik indexen látta az eddigi legkisebb számot. A belső ciklus végigmegy, csak vizsgálódik (ami nagyon gyors), és csak a legvégén, amikor már biztosan tudja, hol van a legkisebb elem, hajt végre egyetlenegy cserét.

32. feladat

Generáljunk 10 számot, írjuk ki őket, majd rendezzük csökkenő sorrendbe (elöl a legnagyobbak) minimumkiválasztásos rendezéssel! Mivel most csökkenő sorrendet kérünk, valójában mindig a "maximumot" fogjuk kiválasztani a maradékból. Név: Minimumkiválasztásos rendezés (Csökkenő)

Megoldás:

static void Main(string[] args)
{
    int[] a = new int[10];
    Random vsz = new Random();

    Console.WriteLine(" Az eredeti tömb:");
    for (int i = 0; i < 10; i++)
    {
        a[i] = vsz.Next(101);
        Console.Write("{0,4}", a[i]);
    }
    Console.WriteLine("\n");

    // --- MINIMUMKIVÁLASZTÁSOS RENDEZÉS ALGORITMUSA ---
    for (int i = 0; i < 10 - 1; i++)
    {
        int maxIndex = i; // Feltételezzük, hogy az aktuális 'i' helyen van a legnagyobb szám

        for (int j = i + 1; j < 10; j++)
        {
            if (a[j] > a[maxIndex]) // Keresünk nála még nagyobbat (mert csökkenőbe rendezünk)
            {
                maxIndex = j; // Csak az indexét jegyezzük meg, NINCS csere!
            }
        }

        // Amikor a belső ciklus lefutott, megnézzük, találtunk-e nagyobbat az eredetinél
        if (maxIndex != i) 
        {
            // Csak ekkor, és csak egyszer cserélünk!
            int seged = a[i];
            a[i] = a[maxIndex];
            a[maxIndex] = seged;
        }
    }

    Console.WriteLine(" A rendezett számok (csökkenő):");
    for (int i = 0; i < 10; i++)
    {
        Console.Write("{0,4}", a[i]);
    }

    Console.ReadKey();
}

Összefoglaló - Mi a különbség a kettő között?

Mindkét algoritmus ugyanazt a végeredményt adja. A különbség a háttérben elvégzett munka mennyiségében van. Képzeld el, hogy a tanár egy 30 fős osztályt akar magasság szerint sorba állítani.

  • Az egyszerű cserés módszerrel a tanár az első embert folyton cserélgeti a sorban mindenkivel, aki nála alacsonyabb, amíg nagy nehezen be nem kerül a legkisebb előre. Rengeteg a mozgás.

  • A minimumkiválasztásos módszernél a tanár végignéz az osztályon, kiválasztja szemmel a legalacsonyabb diákot, és megkéri, hogy cseréljen helyet a sor elején állóval. Egyetlen helycsere történt! Ez sokkal hatékonyabb.