1 Vnitřní řazení s využitím dynamických struktur Tvorba spojového seznamu je vcelku triviální záležitostí: a)Vytvořím prázdný seznam příkazem LIST:=nil → LIST (1) za předpokladu dříve deklarované proměnné var LIST: WSKAZ; opírající se o potřebné definice typů např. ve tvaru type COSI = string[10] {popř. COSI = integer apod.} WSKAZ = ^STRU; STRU = record IM: COSI; WS: WSKAZ end; nil
2 b)Zařazujeme do spojového seznamu prvky v pořadí jejich příchodů. Za předpokladu deklarace var Novy: WSKAZ; pak tento postup řeší příkazy NEW(NOVY); (2) NOVY^.WS := LIST; (3) LIST := NOVY (4) Samozřejmou součástí musí být tak přiřazení vstupující hodnoty typu COSI do přidávací struktury např. NOVY^.IM:=‘Aneta‘ popř. readln(NOVY^.IM) apod. (2´) nil NOVY LIST (3) (2) (4)
3 Po dalším zopakování příkazů (2), (2´), (3) a (4) dostávám tvar Takto stále přidávám další a další struktury, přičemž první je stále poslední a každá nově vytvořená se umístí vždy na začátek spojového seznamu. ‘Berta‘ NOVY LIST (3) (2) (4) ‘Aneta‘ nil (2‘)
4 Procedura pro vložení nové struktury do spojového seznamu (na jeho počátek) pak může být ve tvaru: procedure INSNOVY(var L: WSKAZ; A: COSI); var POM: WSKAZ; begin NEW(POM); POM^.IM := A; POM^.WS := L; L := POM end;
5 Vytiskneme-li hodnoty umístěné do spojového seznamu procedurou TISK ve tvaru procedure TISK(L: WSK); begin while L <> nil do begin writeln(L^.IM); L := L^.WS end end; získávám seznam hodnot v opačném pořadí, než jsme je zadávali.
6 Zařazení nové vstupující hodnoty do spojového seznamu podle její velikosti – tj. její vřazení na příslušné místo spojového seznamu – vyžaduje poněkud odlišnější postup 9nil 71115nil4 LIST NOVY NEXT PRE
7 Nechť ukazatel NEXT postupně ukazuje na jednotlivé prvky spojového seznamu (od NEXT:= LIST do NEXT:= nil ). Je zřejmé, že je-li NOVY^.IM <= NEXT^.IM, patří nově zařazovaná hodnota před hodnotu, na kterou právě ukazuje NEXT. Budeme-li v ukazateli před udržovat adresu předchozího prvku tak jak je patrno z obrázku, je zařazení nového prvku již jednoduchou záležitostí: NOVY^.WS := NEXT; PRE^.WS := NOVY; NEXT := nil {prvek je zařazen}
8 Ještě vyřeším obligátní záležitosti okrajových řešení: patří-li nový prvek na začátek spojového seznamu, tj. NEXT = LIST, pak jeho zařazení řeší příkazy NOVY^.WS := LIST; LIST := NOVY; NEXT := nil {prvek je zařazen} patří-li nový prvek na konec spojového seznamu, tj. NEXT = nil, pak jeho zařazení řeší příkazy NOVY^.WS := NEXT; {totéž jako NOVY^.WS := nil} PRE^.WS := NOVY; Kompletní řešení problematiky tvorby uspořádaného spojového seznamu přináší Příklad tvorby uspořádaného seznamu
9 Je zřejmé, že aplikace metod uváděných v souvislosti s vnitřním řazením v poli je vcelku zbytečná. Přesto, existuje-li již neuspořádaný spojový seznam, je možno tu či onu metodu s větší či menší efektivitou použít. Jako výhodná se jistě jeví další vkládací metoda přímého výběru (straight selection) a pro zajímavost uvedeme i metodu quicksort.
10 Procedure STRSEL(var FLIST:WSKAZ); var FIRST, NEXT, PRE, HLED, POM : WSKAZ; begin FIRST:=FLIST; FLIST:=nil; repeat HLED:=FIRST; NEXT:=FIRST^.WS; POM:=FIRST; repeat if NEXT^.IM>HLED^.IM then begin PRE:=POM; HLED:=NEXT end; POM:=NEXT; NEXT:=NEXT^.WS until NEXT=nil; if HLED=FIRST then begin POM:=FIRST^.WS; FIRST^.WS:=LIST; LIST:=FIRST; FIRST:=POM end else begin PRE^.WS:=HLED^.WS; HLED^.WS:=LIST; LIST:=HLED; end until FIRST^.WS=nil; FIRST^.WS:=LIST; LIST:=FIRST end;
11 Procedure QUICKSORT(var ZAC, KON: WSKAZ); procedure ROZDEL(var ZAC, KON : WSKAZ); var pivot, POM, NEXT : WSKAZ; begin pivot := ZAC; POM := pivot^.WS; NEXT := pivot; repeat if POM^.IM < pivot^.IM then begin {hodnota je mensi, strcime pred pivota} {premostime diru vzniklou odstranenim prvku} NEXT^.WS := POM^.WS; {presuneme prvek na spravne misto} POM^.WS := ZAC; ZAC := POM; if POM=KON then KON:=NEXT end else begin {posuneme se na dalsi prvek} NEXT := POM; end; POM := NEXT^.WS; until (POM=nil) or (POM=KON^.WS); if ZAC <> pivot then ROZDEL(ZAC, pivot); if (pivot <> KON) and (pivot^.WS <> KON) and (pivot^.WS <> nil) then ROZDEL(pivot^.WS, KON); end; begin rozdel(ZAC, KON); end;
12 Ukázka konkrétního programu s oběma výše uvedenými podprogramy je „Příklad řazení v dynamických strukturách“