/** * \brief Linked List : Sorting Algorithms * * * \author Mihael Schmidt * \date 2009-02-17 * */ H NOMAIN *--------------------------------------------------------------- * Prototypen *--------------------------------------------------------------- /copy 'llist_h.rpgle' /copy 'llist_in_h.rpgle' /copy 'ceeapi_h.rpgle' *------------------------------------------------------------------------- * Procedures *------------------------------------------------------------------------- /** * \brief Insertion sort * * The list will be sorted inline. * * \author Mihael Schmidt * \date 2009-02-17 * * \param Pointer to the list */ P list_sort_insertionSort... P B export D PI D listPtr * const * D header DS likeds(tmpl_header) based(listPtr) D keepRunning S N inz(*on) D entryPtr1 S * D entry1 DS likeds(tmpl_entry) based(entryPtr1) D entryPtr2 S * D entry2 DS likeds(tmpl_entry) based(entryPtr2) D rc S 10I 0 D length S 10U 0 D shouldSwap S N inz(*off) D top S N inz(*off) D bottom S N inz(*off) /free if (header.size <= 1); return; endif; entryPtr1 = getListEntryDs(listPtr : 0); entryPtr2 = getListEntryDs(listPtr : 1); dow (keepRunning); if (entry1.length < entry2.length); length = entry1.length; else; length = entry2.length; endif; rc = memcmp(entry1.value : entry2.value : length); if (rc > 0); shouldSwap = *on; elseif (rc = 0 and entry1.length > entry2.length); // check the length of the values shouldSwap = *on; else; // correct order => go down again shouldSwap = *off; endif; if (shouldSwap); top = *off; bottom = *off; internal_swap(listPtr : *omit : *omit : entryPtr1 : entryPtr2); // // get next entries to check // // check if we are already at the top if (entry2.prev <> *null); // note: entry2 is now above entry1 // go one up entryPtr1 = entry2.prev; else; // we are at the top, now go down again top = *on; // skip one entry because we just made the check if (entry1.next <> *null); entryPtr2 = entry1.next; else; bottom = *on; endif; endif; else; // check next entries if (bottom); // need to go up if (entry1.prev <> *null); entryPtr2 = entryPtr1; entryPtr1 = entry2.prev; else; top = *on; // go down entryPtr1 = entryPtr2; entryPtr2 = entry1.next; endif; else; // need to go down if (entry2.next <> *null); entryPtr1 = entryPtr2; entryPtr2 = entry1.next; else; bottom = *on; if (entry1.prev <> *null); // go up again entryPtr2 = entryPtr1; entryPtr1 = entry2.prev; else; top = *on; endif; endif; endif; endif; // if both ends have been visited without change => end loop if (top and bottom); keepRunning = *off; endif; // reset things shouldSwap = *off; enddo; /end-free P E