Sapludināt kārtošanas

Link: http://alumnus.caltech.edu/~pje/mergesor.html

Nosaukums:
sapludināšanas kārtošanas
valodas:
C
Autors:
Philip J. Erdelsky

[email protected]
http://www.alumni.caltech.edu/~pje/

datums:
1996. gada 23. februārī
lietošanas:
atklātībai; lietošanas ierobežojumi
pārnesamību:
jebkura C kompilatoru
atslēgvārdus:
kārtošanas
Abstract:
A C funkcija, lai kārtotu failu, izmantojot patvaļīgu lasīšanas, rakstīšanas un salīdzinājums funkcijas un lenšu sapludināšanas algoritms, kas ir O (n log n) visos gadījumos. Funkcija ir nav rekursīvi un re-entrant.

Funkcija merge_sort() kārtos gandrīz jebkura veida failu, izmantojot lasīšanas, rakstīšanas un salīdzinājums funkcijas nodrošina izsaucēja programma.

To kārto uzskaiti par mainīgo lielumu.
Tas prasa O (n log n) salīdzinājumu, kur n ir ieraksti, neskatoties uz sākuma pasūtījumu skaits. Laiks, lai kārtotu failu ir paredzama un konsekventa. Šis izpildījums ir zināms, ka optimāls vispārējās kārto.
Skaitu, cik reizes ieraksts ir jābūt lasīt vai wirtten, lai, fails diskā ir arī (n log n) O.
Algoritms ir iteratīvs, nav rekursīvi, tāpēc nav problēmu ar steka pārpilde. Steka prasība ir prognozējama, konsekventu un nelielu.
Tas prasa apmēram diskā nepietiek vietas, lai turiet abas faila kopijas. Sakārtotā fails tiek atstāts šajā telpā.
Tas prasa vismaz nepietiek atmiņas saglabāt trīs ierakstus, bet tā darbosies ātrāk, ja tas ir aprīkots ar papildu atmiņu.
Tas izsauc tmpfile ( ) veidot ne vairāk kā četras pagaidu failus vienlaikus.
Nesakārtotā failā secīgi nolasa un sakārtotā fails tiek ierakstīts secīgi. Līdz ar to tās var lentes, ievadizvades plūsmām vai citām ierīcēm, kas stingri secīgas.

Funkcijas izsaukums ir šāds:

rezultāts = merge_sort (unsorted_file, sorted_file, lasīt, rakstīt, salīdzināt,
rādītāju, max_record_size, block_size, pcount);

Izsaukšanas programma jānorāda šādi parametri:

failu * unsorted_file;
Faila rādītāju faila jākārto. Fails ir veiksmīgi atvērts lasīšanai un failu rādītājs jānovieto faila sākumā.
Failu * sorted_file;
Faila rādītāju sakārtotā failam. Fails ir veiksmīgi atvērt rakstīšanai un failu rādītājs jānovieto faila sākumā.
int (* read)();
Funkcija, kas skan vienu ierakstu.
int (* write)();
Funkcija, kas raksta vienu ierakstu.
int (* compare)();
Funkcija, kas salīdzina divus ierakstus.
neesošu * rādītājs;
Lietotāja definēto rādītāju var nodot (* read)(), (*write)() un (ja tās tiek sauktas par *compare)() funkcijas.
neparakstītu max_record_size;
Maksimālais ieraksta, kad to lasa savā atmiņā baitu skaits. Tas nav jābūt tādam pašam kā jautājuma apspriešanu lielumu, ja tas atrodas fails.
neparakstītu ilgi block_size;
Tikt saglabāti atmiņas vai 1l ja atmiņas šķirošana neizlieto ierakstu skaits.
neparakstīta sen * pcount;
Rādītāju, lai mainīgais saņemtu ierakstu skaits (ja tāda ir veiksmīga) vai vērtību NULL, ja šī informācija nav jāatgriež.

Funkcija atgriež šādas vērtības:

int rezultāts;
Rezultāta kods:

0 sekmīga kārtošana
1 nepietiek atmiņas
2 faila izveides kļūda
3 faila rakstīšanas kļūda

nesakārtotā un sakārtoti faili netiks attīta vai slēgts. Katrs fails tiks atstāta vaļā, ar faila rādītāju novieto faila beigās. Tomēr, ja divi failu rādītāji ir vienādi, fails tiek attīta un sakārtoti ieraksti tiks rakstīts pār to.

(*Read)() funkciju sauc merge_sort() šādi un jāizlasa viena ieraksta katru reizi tiek saukts par (izņemot gadījumus, kad tiek konstatēta nesakārtotā faila beigas):

n = (* lasīt) (fp, buferis, rādītāju);

FAILU * fp;
Faila rādītāju nesakārtotā failu vai pagaidu fails, ko izveidojis izsaucēja tmpfile ( ).
neesošu * bufera;
Rādītāju uz bufera saņemt vienu ierakstu. Šo buferšķīdumu var glabāt ne vairāk max_record_size baiti.
neesošu * rādītājs;
Rādītāju kā arguments nodotas merge_sort() kopiju.
int n;
To baitu skaits, kas ieraksta vai nulle, ja tika mēģināts lasīt pagātnes nesakārtotā faila beigas.

Ja šī funkcija atgriež nulli, tas nav sauks atkal par vienu un to pašu failu. Tiks veikts neviens mēģinājums lasīt agrāk pagaidu faila beigās.

Ieraksts, kas ir lielāks par norādīto maksimālo lielumu apgriezts vai jārisina kādā citā piemērotā veidā. Funkcija katastrofāli cietīs neveiksmi, ja buferis ir atļauts pārpilde vai vērtību, ko atgriež (*read)() ir lielāks par maksimālo ierakstu.

Ieraksta formātu var mainīt, ja tas ir lasāms atmiņā, ar nosacījumu, ka:

izmaiņas ir saderīgi ar (*write)() un (*compare)() funkcijas un
atgrieztajai vērtībai (*read)() funkcijai ir jābūt ieraksta baitu skaits esot atmiņas buferī.

 

Piemēram, line terminator \r\n DOS/Windows var pārvērst \n, kad to lasa atmiņas.

(*Write)() funkciju sauc šādi, un jāieraksta viena ieraksta katru reizi, kad to sauc:

n = (* rakstīt) (fp, buferis, rādītāju);

FAILU * fp;
Faila rādītāju sakārtotā failu vai pagaidu fails, ko izveidojis izsaucēja tmpfile ( ).
neesošu * bufera;
Rādītāju uz bufera, turot vienā ierakstā, kā lasīt atmiņas, (* read)().
neesošu * rādītājs;
Rādītāju kā arguments nodotas merge_sort() kopiju.
int n;
Nenulles vērtība par veiksmīgu rakstīšanu; nulli, lai diskā nepietiek vietas.

Ievērojiet, ka ierakstu garums nav nodots kā parametrs. Tai jābūt ietvertiem, tieši vai netieši pats ieraksts vai kādā citā vietā, kas pieejama (*write)() funkcija.

(*Compare)() funkciju sauc salīdzināt divus ierakstus šādi:

n = (* salīdzināt) (p, q, rādītāju);

spēkā neesošu * p;
Rādītāju uz pirmo ierakstu, kas satur kā buferis ielasīt atmiņu, izmantojot (* read)().
neesošu * q;
Rādītāju, lai buferšķīdums, kas satur otro ierakstu, kā var ielasīt atmiņu, izmantojot (* read)().
neesošu * rādītājs;
Rādītāju kā arguments nodotas merge_sort() kopiju.
int n;
Salīdzinājuma rezultātā šādi:

> 0, ja * p ir pēc * q sakārtotā secībā
< 0, ja * p ir jābūt pirms * q sakārtotā secībā
0, ja ordenis * p un * q nav nozīmes

Kārtot šādi ieņēmumi:

ieraksti ir nolasīti no faila nesakārtotā un ierakstīti divi pagaidu failus no blokiem. Katrā blokā ir norādījis block_size arguments (izņemot pēdējo bloku, kas var saturēt mazāk ierakstu) ierakstu skaits, un tas tiek kārtots atmiņā pēc izsaucēja sort_linked_list() pirms tas ir rakstīts uz pagaidu failu.
Pagaidu faili tiek sakārtoti pēc tam apvienojot bloku skaits iet. Katrā reizē kvar-tālu attālumā no abiem avota failiem blokus, kas satur divreiz vairāk ieraksti ir sapludināti, un tiek ierakstīti divi izvades failiem. Process beidzas, kad bloka izmērs ir vienāds ar vai pārsniedz faila lielums un visi ieraksti ir vienā failā, kas ir kārtoti failu.

Kārtošanas var neizdoties, ja

sarunas par malloc() atgriež vērtību NULL, jo nepietiek atmiņas vai
sarunas par tmpfile ( ) atgriež vērtību NULL, jo ir pārāk daudz atvērtu failu vai
sarunas uz (*write)() atgriež nulli, jo nepietiek vietas diskā.

Vai tāda ir veiksmīga vai nē, tiks deallocated visas iedalīto atmiņu blokus, un tiks slēgts un dzēst visus pagaidu failus. Ja kārtošanas neizdodas, fails norādes par nešķirotu un kārtot failus paliks tur, kur tie izrādījās.

Funkcija merge_sort() ir reentrant, ja reentrant funkcijas, kuras tā aicina:

(*compare)()
fclose()
free()
malloc()
memcpy()
(*read)()
rewind()
tmpfile ( )
(*write)()

Saskaņā ar DOS/Windows, tmpfile ( ) izveido BINĀRO failu. Tomēr tas parasti rada nekādas problēmas, pat ja nesakārtotā un sakārtoti faili ir teksta faili, jo DOS/Windows apstrādā Reklāmguvumi konsekventi.

Ja diskā ir ārkārtīgi saspringts, kārtošanas var modificēt, lai lietotu atstarpe, kuru aizņem nesakārtotā failu. Nesakārtotā failu, pagaidu failus un sakārtotā failu pēc tam var ietilpt kosmosā aptuveni divtik liela kā nesakārtotā failu. Lai veiktu šādas modifikācijas, ievietojiet kodu, lai dzēstu nesakārtotā failu, pēc tam, kad tas ir ticis lasīts. Ievērojiet, ka, ja šī tehnika tiek izmantota, sakārtotā un nesakārtotā failiem jābūt dažādām un arguments iet struktūra var kļūt nedaudz mazāk eleganti, jo funkcijas izsaukums, lai izdzēstu failu parasti ir nepieciešama, failu specifikācijas, nevis tikai faila rādītāju.

Merge_sort() funkcija nav stabili; t.i., nesaglabā relatīvo novietojumu, kā divus ierakstus, kuriem (*compare)() funkcija atgriež nulli. Funkcija stable_merge_sort() ir šo īpašumu. Tomēr papildu iespēja veic cenu: četru baitu ieraksta numurs tiek pievienots katrā ierakstā, atrodoties atmiņā vai pagaidu failu. Tas palielina diska un atmiņas prasības, ar ievērojamu summu, ja ieraksti ir maza.

VEIDA lietderību ilustrē stable_merge_sort() izmantošanu. Tas ir DOS vai UNIX filtru, kas kārto rindas teksta failā. Maksimālais rindas garums ir MAX_LINE rakstzīmes, neieskaitot pārvadāšanas atgriešanos un līnija barības, katras rindiņas beigās. Lietderība tiks priekšlaikus kārtošanas un rāda kļūdas ziņojumu, ja tas skan rindas, kas satur vairāk nekā MAX_LINE rakstzīmes. MAX_LINE vērtība ir noteikta 255, bet to var mainīt ar recompiling lietderība.

Lietderība sauc šādi:

KĀRTOŠANA < unsorted_file > sorted_file M N

Kārtot ietver kolonnas numuru M n, ieskaitot, kur kolonnai ir ciparu nulle. Ja N ir izlaists, kārtot ietver M kolonnu un visus kolonnas pa labi no tā. Ja tiek izlaisti gan M un N, visas kolonnas tiek izmantoti kārtošanā.

Līniju, kurā ir mazāk par N + 1 kolonnas tiek kārtots tā, it kā tas tika uzrādīts ar nulles labajā galā.

Rakstzīmes tiek sarindoti pēc to ASCII kodi, uzskata NEPARAKSTĪTU baiti.

Pirmkodu teksta formātā:

Leave a Reply

Your email address will not be published. Required fields are marked *