3. C#

3.8. Seřazení prvků pole

Pro seřazení prvků v jednotlivých řádcích naplněného dvourozměrného pole budeme, jako u předchozího jednorozměrného pole, využívat algoritmus bublinkového řazení (anglicky "Bubble Sort"). Algoritmus funguje na principu průchodů prvky v řádku matice (řádka ve své podstatě představuje vektor). Vždy jsou porovnávány dva prvky. U vzestupného řazení prvků řádku je testována podmínka, pokud je aktuální prvek větší než následující, dojde k prohození těchto prvků (jedná se o vzestupné řazení). Po každém průchodu se dostaneme do určité fáze seřazení. Řádek je seřazen, pokud při průchodu prvků řádku nedošlo k žádnému prohození prvků. Tímto způsobem seřadíme všechny řádky matice - viz Obrázek 1.

Bublinkové řazení prvků dvourozměrného pole

Obrázek 1: Bublinkové řazení prvků dvourozměrného pole

Následující obrázek ilustruje, jak prohodit dva prvky např. v počátečním řádku matice - viz Obrázek 2. 

Prohození dvou prvků v řádku matice

Obrázek 2: Prohození dvou prvků v řádku matice

Metoda SeraditPole, deklarovaná v regionu Operace s polem, je bez návratu. Metoda přijímá tři parametry - v prvním parametru je uložen počet řádků matice, druhý obsahuje počet sloupců matice a třetí parametr obsahuje matici, jejíž prvky v jednotlivých řádcích mají být seřazeny vzestupně - viz Kód 1. Metoda obsahuje následující lokální proměnné:

  • pom - pomocná proměnná pro dočasné uložení prvku
  • i - index řádku matice (deklarace přímo v cyklu)
  • j - index sloupce matice (deklarace přímo v cyklu)
  • b - logická proměnná obsahující informaci, zda došlo k prohození některých sousedních prvků (tj. zda je již řádek seřazen, pokud b == false)

Uvnitř metody jsou umístěny tři cykly. První vnější cyklus s krokem slouží pro procházení jednotlivých řádků matice. Další cyklus s podmínkou na konci, se stará o kontrolu, zda jsou již všechny prvky v řádku kompletně seřazeny. Před proběhnutím navazujícího vnitřního vnořeného cyklu s krokem pro průchod jednotlivých sloupců matice, v nichž jsou umístěny prvky, je zapotřebí provést nastavení proměnné b na hodnotu false, tj. b = false. Tím je řečeno, že ještě před proběhnutím porovnání dvojic prvků v řádku neproběhlo žádné prohození dvou sousedních prvků. Uvnitř těla třetího cyklu s krokem je potřeba vždy porovnávat dva sousední prvky. U řídící proměnné j třetího cyklu s krokem je potřeba se při procházení sloupců zastavit na předposledním sloupci (horní mez intervalu hodnot indexu řídící proměnné j), protože porovnáme pouze předposlední a poslední prvek v řádku. Pokud bychom nechali řídící proměnnou j cyklu zastavit až na posledním sloupci v řádku, porovnávali bychom uvnitř těla cyklu poslední prvek s dalším prvkem, který však neexistuje. Pokud je aktuálně procházený prvek při vzestupném řazení větší než následující prvek (s indexem o 1 větší), je zapotřebí tyto prvky prohodit na základě principu, který jsme již probírali v předchozím textu. V opačném případě, není zapotřebí prvky prohazovat. Pokud došlo alespoň k jednomu vzájemnému prohození prvků, je do proměnné b přiřazena hodnota true a díky tomu bude v cyklu s podmínkou na konci provedena další iterace. V případě, že úvodní předpoklad (b == true) stále platí i na konci průchodu prvky v řádku, dojde k přechodu na nový řádek matice - viz Kód 1.

/// <summary>
/// Vzestupné řazení prvků řádků matice
/// </summary>
/// <param name="m"> počet řádků matice </param>
/// <param name="n"> počet sloupců matice </param>
/// <param name="pole"> matice, kde prvky v každém řádku mají být setříděny vzestupně </param>
static void SeraditPole(int m, int n, int[,] pole)
{
    /* Deklarace: 'pom' ... pomocná proměnná pro dočasné uložení prvku; 'b' ... logická proměnná 
     * obsahující informaci, zda došlo k prohození některých sousedních prvků; 'i' ... index řádku 
     * matice; 'j' ... index sloupce matice */
    int pom;
    bool b;
 
 
    // Pro všechny řádky matice
    for (int i = 0; i < m; i++)
    {
        // Opakuj tak dlouho u každé řádky, dokud bude docházet k prohození prvků
        do
        {
            // Nedošlo k prohození sousedních prvků
            b = false;
            // Pro všechny sloupce matice
            for (int j = 0; j < n - 1; j++)
            {
                /* Pokud je hodnota sousedícího prvku větší než hodnota aktuálně
                 * testovaného prvku, pak... */
                if (pole[i, j] > pole[i, j + 1])
                {
                    // Ulož hodnotu aktuálního prvku do pomocné proměnné
                    pom = pole[i, j];
 
                    // Ulož hodnotu sousedícího prvku do aktuálního prvku
                    pole[i, j] = pole[i, j + 1];
 
                    // Ulož hodnotu z pomocné proměnné do sousedícího prvku
                    pole[i, j + 1] = pom;
 
                    // Došlo k prohození sousedních prvků
                    b = true;
                }
            }
        }
        // Testování, zda došlo k prohození některých sousedních prvků
        while (b == true);
    }
}

Kód 1: Deklarace statické metody bez návratu s názvem SeraditPole