| 发表于:2007-08-17 16:44:3720楼 得分:0 |
最后是mergesort: #if defined(mergesort) && defined(win32) #define sortcompare(psp, pp1, i1, pp2, i2) \ (psp-> pfncmp(pp1[i1], pp2[i2], psp-> lparam)) // // this function merges two sorted lists and makes one sorted list. // psp-> pp[ifirst, ifirst+cites/2-1], psp-> pp[ifirst+citems/2, ifirst+citems-1] // void near dpa_mergethem(sortparams far* psp, int ifirst, int citems) { // // notes: // this function is separated from dpa_mergesort2() to avoid comsuming // stack variables. never inline this. // int chalf = citems/2; int iin1, iin2, iout; lpvoid * ppvsrc = &psp-> pp[ifirst]; // copy the first part to temp storage so we can write directly into // the final buffer. note that this takes at most psp-> cp/2 dword 's hmemcpy(psp-> ppt, ppvsrc, chalf*sizeof(lpvoid)); for (iin1=0, iin2=chalf, iout=0;;) { if (sortcompare(psp, psp-> ppt, iin1, ppvsrc, iin2) <= 0) { ppvsrc[iout++] = psp-> ppt[iin1++]; if (iin1==chalf) { // we used up the first half; the rest of the second half // should already be in place break; } } else { ppvsrc[iout++] = ppvsrc[iin2++]; if (iin2==citems) { // we used up the second half; copy the rest of the first half // into place hmemcpy(&ppvsrc[iout], &psp-> ppt[iin1], (citems-iout)*sizeof(lpvoid)); break; } } } } // // this function sorts a give list (psp-> pp[ifirst,ifirst-citems-1]). // void near dpa_mergesort2(sortparams far* psp, int ifirst, int citems) { // // notes: // this function is recursively called. therefore, we should minimize // the number of local variables and parameters. at this point, we // use one local variable and three parameters. // int chalf; switch(citems) { case 1: return; case 2: // swap them, if they are out of order. if (sortcompare(psp, psp-> pp, ifirst, psp-> pp, ifirst+1) > 0) { psp-> ppt[0] = psp-> pp[ifirst]; psp-> pp[ifirst] = psp-> pp[ifirst+1]; psp-> pp[ifirst+1] = psp-> ppt[0]; } break; default: chalf = citems/2; // sort each half dpa_mergesort2(psp, ifirst, chalf); dpa_mergesort2(psp, ifirst+chalf, citems-chalf); // then, merge them. dpa_mergethem(psp, ifirst, citems); break; } } bool near dpa_mergesort(sortparams far* psp) { if (psp-> cp==0) return true; // note that we divide by 2 below; we want to round down psp-> ppt = localalloc(lptr, psp-> cp/2 * sizeof(lpvoid)); if (!psp-> ppt) return false; dpa_mergesort2(psp, 0, psp-> cp); localfree(psp-> ppt); return true; } #endif // mergesort | | |
|