Jednosměrně vázaný seznam
Vytvořte modul programu, který bude schopen uložit větší množství hodnot do pole. Předpokládejte, že pole může být i velice řídké (a mělo by tedy docházet i k jisté „kompresi“ při ukládání dat). Vyřešte odebírání prvků (se současným rušením těchto prvků – bude-li to nutné). Předpokládá se i požadavek na řazení prvků v poli podle velikosti.
K realizaci použijte lineární seznam a pro něj napište funkce:
Vytvoření seznamu – ve funkci, dynamicky (pomocí alokací)
Tisk seznamu – ve funkci
Zrušení seznamu – ve funkci (odalokování)
Seřazení seznamu – ve funkci podle indexů (od největšího)
Pozn.:
Při programování je často nutné udržovat větší množství dat. Jedním z možných přístupů je použití pole (spojitá část buněk v paměti). Výhodou pole je, že se v něm snadno manipuluje (náhodný přístup), snadno se přidává a ubírá poslední prvek, Jeho nevýhodou je, potřebujeme-li prvek vložit/vybrat uprostřed pole. Tato činnost je časově náročná z důvodu nutnosti přeskládat prvky za použitou pozicí.
Druhou skupinou pro ukládání dat jsou přístupy založené na struktuře, která obsahuje dvě části – datovou a „vazební“. V datové části se nacházejí data, vazební část zajišťuje propojení jednotlivých struktur, která je realizovaná pomocí ukazatelů (jeden, dva ...). Výhodou je snadné vkládání a vybírání prvků, které se skládá pouze s přesunu ukazatelů, nevýhodou je sekvenční přístup k prvkům a vyšší datová náročnost (pomocné ukazatele). Výhodou je množství realizovatelných prvků ((oboustranný) seznam, LIFO, FIFO, stromy, pole …).
Pro danou úlohu se tedy hodí jednosměrně vázaný (lineární) seznam. Umožňuje rychlé vložení a vypuštění prvku (zvláště výhodné v setříděné variantě) bez nutnosti provádět posuvy prvků (vytvoření místa pro vkládaný prvek a posun prvků po odebrání prvku). Za to platíme paměťovým místem pro uložení „režijní“ proměnné, kterou je ukazatel na další prvek.
Je tedy nutné napsat program pracující s jednosměrně vázaným seznamem (základem seznamu je struktura, která obsahuje v datové části „užitečné“ hodnoty a pro vazbu ukazatel na prvek stejného typu (strukturu). Tento ukazatel ukazuje na následující prvek seznamu, nebo nabývá hodnotu NULL je-li posledním prvkem.) Důležité je vyřešení uložení informace o počátku seznamu, která je vstupem do všech funkcí (důkladně promyslete).
Krok 0: založte si nový projekt – zdrojový soubor
projektu (funkce main, volající funkci test ve které budou volány
následující funkce), zdrojový a hlavičkový soubor seznamu.
Krok
1: nadefinujte strukturu seznamu a vytvořte její proměnnou
(definice struktury bude v *.h souboru, proměnná v main, je nutné
zajistit nulování=inicializaci)
Krok 2: napište funkci pro
přidání prvku na konec seznamu (přidejte do seznamu 20 prvků s
hodnotami 1 až 20)
Krok 3: napište funkci pro zrušení
seznamu (zavolejte 2krát po sobě, poté opět proveďte přidání prvků
jako v kroku 2. (Tím se zjistí, zda je ošetřeno vícenásobné
odalokování, a zda po odalokování je možné seznam znovu použít)
Krok
4: napište funkci pro tisk seznamu (vytiskněte seznam)
Útržek
kódu této funkce by mohl vypadat například takto:
akt
= pocatek;
while (akt != NULL) {
printf(“%f “,
akt->data);
akt = akt->dalsi;
}
Krok 5: napište funkci pro seřazení prvků seznamu od
největšího po nejmenší.
Krok 6: napište funkci pro zařazení
prvku na danou pozici (zařaďte prvek s hodnotou 100 na 14-tou pozici,
vytiskněte, zařaďte prvek s hodnotou 200 na pozici 21,-1, 0 a 200,
vytiskněte). Nebude-li pozice existovat, nezařazujte.
Krok 7:
napište funkci pro odebrání prvku z dané pozice (odeberte prvky se
stejnými čísly jako v příkladě 5 (v opačném pořadí) a vytiskněte) –
prvek je odebrán ze seznamu a vrácen volající funkci.
Krok 8:
Doplňte program tak aby pracoval korektně. Zkuste volání (například
tisk) ihned po vytvoření proměnné Seznam a; tisk(a);
Pro inspiraci jedna z možných „koster“ programu
struct LinSeznam {
// vlastní data
// ukazatel na další
prvek LinSeznam
};
int Vytvor(LinSeznam ** UkNaPrvni, int pocet)
{
// vytvorte
pocet prvku LinSeznamu
// jako hodnoty naplňte číslem vytvoření 1
až počet
return 1; // uspech
}
void TiskniSeznam(LinSeznam *UkNaPrvni)
{
// vytisknout
seznam
}
void SetridSeznam(LinSeznam **UkNaPrvni)
{
}
int ZrusSeznam(LinSeznam **UkNaPrvni)
{
// zrusi seznam
int
pocet = 0;
return pocet ; // vrati pocet zrusenych
}
int main(int argc, char* argv[])
{
LinSeznam *Prvni;
Vytvor(
,5); // pokusime se vytvořit pětiprvkový seznam
TiskniSeznam( );
// předáme seznam a vytiskneme
SetridSeznam( ); // předáme seznam
k seřazení
TiskniSeznam( ); // předáme seznam a vytiskneme
ZrusSeznam( ); // předáme seznam a zrušíme jeho
prvky
SetridSeznam( ); // předáme seznam k seřazení
TiskniSeznam(
); // předáme seznam a vytiskneme
ZrusSeznam( ); // předáme seznam
a zrušíme jeho prvky
return 0;
}
poslední úpravy 2010-10-18