JNIEXPORT jint JNICALL Java_edu_berkeley_bid_CUMATD_fsort (JNIEnv *env, jobject obj, jobject jpkeys, jint n, jint desc) { double *pkeys = (double *)getPointer(env, jpkeys); return fsort(pkeys, n, desc); }
/* 参数分别为待排序数组,起始点,结束点,调用的排序函数 将输出函数执行时间*/ void sort_test(int *list, int l, int r, void (*fsort)(int *list, int l, int r)) { clock_t before; before = clock(); fsort(list, l, r); output(list, r-l+1); double elapsed = clock() - before; printf("time: %.3fs \n\n", elapsed/CLOCKS_PER_SEC); }
double get_sort_time(int *pa, int len, void (fsort)(int * , int )) { # if 0 // 计时方法1 const clock_t begin = clock(); fsort(pa, len); const clock_t end = clock(); return (double)(end-begin)/CLOCKS_PER_SEC ; #endif #if 0 // 计时方法2 DWORD begin = GetTickCount(); fsort(pa, len); DWORD end = GetTickCount(); return end - begin; #endif StartCounter(); fsort(pa, len); return GetCounter() ; }
int fsort_test_single(float *pfInput, int nlen, int nRightRet, float *pfRightOut) { int i; int nRet = fsort(pfInput, nlen); if (nRet != nRightRet) return 1; if (nRet != 0) return 0; for (i = 0; i < nlen; i++) { if (fabs(pfInput[i] - pfRightOut[i]) > EPS) return 1; } return 0; }
extern int qs_fsort_clean(const char *url, FILE *stream) { return fsort(url, stream, true); }
extern int qs_fsort(const char *url, FILE *stream) { return fsort(url, stream, false); }
double getdelta(double *ph, double *palpha, const double *w, const double thetaSQR, const int n, double *wQ) { double gap,r,h,hSQR,oldhSQR,hubSQR, sumdifv,sumdifw, sumwNT,wj, deltaSQR,alpha; int cardT,cardQ,i,j,STOP; /* ------------------------------------------------------------ gap = sum(w), r = n / theta^2 ------------------------------------------------------------ */ for(i = 0, gap = 0.0; i < n; i++) gap += w[i]; r = n / thetaSQR; /* ------------------------------------------------------------ In the following, T is the index set of w[i]'s that are too small, and Q is the set for which we don't know in the first pass. However, after sorting wQ=w[Q], we will sort that out too. ------------------------------------------------------------ */ /* ------------------------------------------------------------------ IF THETA == 1, WE HAVE: h = sqrt(max(w)) sumdifv = sum (h-v_i) = n*h - sum(sqrt(w)), (v := sqrt(w)) sumdifw = sum (h^2-w_i) = n*h^2 - gap. Use 2 passes to compute sumdifv,sumdifw in stable way. ------------------------------------------------------------------ */ if(1.0 - thetaSQR <= 1E-8){ for(i = 0, hSQR = 0.0; i < n; i++) hSQR = MAX(hSQR,w[i]); h = sqrt(hSQR); sumdifv = 0.0; sumdifw = 0.0; for(i = 0; i < n; i++){ sumdifw += hSQR - w[i]; sumdifv += h - sqrt(w[i]); } } else{ /* ------------------------------------------------------------ 0 < THETA < 1: LB: hSQR = sumwNT/(r-|T|) UB: sumwNT/(r-|T| - |Q|) (Q is first stage inconclusive set) sumdifv = sum_{j in T} (h-v_j) sumdifw = sum_{j in T} (h-w_j) Notice that sum(dif) is much stabler than dif(sum). i : next entry for wQ ------------------------------------------------------------ */ sumwNT = gap; cardT = 0; sumdifv = 0; sumdifw = 0; cardQ = n; i = 0; hSQR = sumwNT / (r - cardT); hubSQR = sumwNT / (r-(n-1)); for(j = 0; j < n; j++){ wj = w[j]; if(wj >= hubSQR){ /* wj >= hubSQR ==> not in T */ --cardQ; hubSQR = sumwNT / (r-cardT-cardQ); } else if(wj < hSQR){ /* wj < hSQR ==> in T */ if(wj <= 0.0) return 1e100; /* error: w should be positive */ ++cardT; --cardQ; hubSQR *= 1 - wj/sumwNT; sumwNT -= wj; oldhSQR = hSQR; hSQR = sumwNT / (r - cardT); sumdifw += (oldhSQR-wj) + cardT * (hSQR-oldhSQR); sumdifv += (sqrt(oldhSQR)-sqrt(wj))+ cardT*(sqrt(hSQR)-sqrt(oldhSQR)); } else /* Inconclusive: j in Q */ wQ[i++] = wj; } mxAssert(i == cardQ,""); /* ------------------------------------------------------------ The same treatment for the Q set, but we sort the (presumably short) wQ first. ------------------------------------------------------------ */ if(cardQ){ fsort(wQ, cardQ); for(STOP = 0, j = 0; !STOP; ){ wj = wQ[j]; if(wj >= hSQR) STOP = 1; else{ ++cardT; sumwNT -= wj; oldhSQR = hSQR; hSQR = sumwNT / (r - cardT); sumdifw += (oldhSQR-wj) + cardT * (hSQR-oldhSQR); sumdifv += (sqrt(oldhSQR)-sqrt(wj)) + cardT * (sqrt(hSQR)-sqrt(oldhSQR)); STOP = (cardQ == ++j); } } } /* cardQ > 0 */ /* ------------------------------------------------------------ Let h := sqrt(hSQR) ------------------------------------------------------------ */ h = sqrt(hSQR); } /* theta != 1 */ /* ------------------------------------------------------------ FOR ALL THETA : alpha = sumdifv/(r*h) deltaSQR = r * ( 2*alpha-alpha^2 - (1-alpha)^2 * sumdifw/gap ) (THE ABOVE DIFFERENCE SHOULD NOT BE NUMERICALLY DANGEROUS, SINCE alpha IS *SIGNIF* BIGGER THAN sumdifw/gap ) ------------------------------------------------------------ */ alpha = sumdifv/ (r*h); deltaSQR = alpha*(2-alpha) - SQR(1-alpha) * sumdifw/gap; *palpha = alpha; *ph = h; return sqrt(r * deltaSQR); }
int main(int argc, char *argv[]) { int ch, i, stdinflag = 0; char cflag = 0, mflag = 0; char *outfile, *outpath = NULL; struct field *fldtab; size_t fldtab_sz, fld_cnt; size_t alloc_size; struct filelist filelist; int num_input_files; FILE *outfp = NULL; struct rlimit rl; struct stat st; setlocale(LC_ALL, ""); /* bump RLIMIT_NOFILE to maximum our hard limit allows */ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) err(2, "getrlimit"); rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) err(2, "setrlimit"); d_mask[REC_D = '\n'] = REC_D_F; d_mask['\t'] = d_mask[' '] = BLANK | FLD_D; /* fldtab[0] is the global options. */ fldtab_sz = 3; fld_cnt = 0; alloc_size = fldtab_sz * sizeof(*fldtab); fldtab = malloc(alloc_size); if (fldtab == NULL) err(1, "Cannot allocate %zu bytes", alloc_size); memset(fldtab, 0, alloc_size); #define SORT_OPTS "bcdD:fHik:lmno:rR:sSt:T:ux" /* Convert "+field" args to -f format */ fixit(&argc, argv, SORT_OPTS); if (!(tmpdir = getenv("TMPDIR"))) tmpdir = _PATH_TMP; while ((ch = getopt(argc, argv, SORT_OPTS)) != -1) { switch (ch) { case 'b': fldtab[0].flags |= BI | BT; break; case 'c': cflag = 1; break; case 'D': /* Debug flags */ for (i = 0; optarg[i]; i++) debug_flags |= 1 << (optarg[i] & 31); break; case 'd': case 'f': case 'i': case 'n': case 'l': fldtab[0].flags |= optval(ch, 0); break; case 'H': /* -H was ; use merge sort for blocks of large files' */ /* That is now the default. */ break; case 'k': alloc_size = (fldtab_sz + 1) * sizeof(*fldtab); fldtab = realloc(fldtab, alloc_size); if (fldtab == NULL) err(1, "Cannot re-allocate %zu bytes", alloc_size); memset(&fldtab[fldtab_sz], 0, sizeof(fldtab[0])); fldtab_sz++; setfield(optarg, &fldtab[++fld_cnt], fldtab[0].flags); break; case 'm': mflag = 1; break; case 'o': outpath = optarg; break; case 'r': REVERSE = 1; break; case 's': /* * Nominally 'stable sort', keep lines with equal keys * in input file order. (Default for NetBSD) * (-s for GNU sort compatibility.) */ posix_sort = 0; break; case 'S': /* * Reverse of -s! * This needs to enforce a POSIX sort where records * with equal keys are then sorted by the raw data. * Currently not implemented! * (using libc radixsort() v sradixsort() doesn't * have the desired effect.) */ posix_sort = 1; break; case 't': if (SEP_FLAG) usage("multiple field delimiters"); SEP_FLAG = 1; d_mask[' '] &= ~FLD_D; d_mask['\t'] &= ~FLD_D; d_mask[(u_char)*optarg] |= FLD_D; if (d_mask[(u_char)*optarg] & REC_D_F) errx(2, "record/field delimiter clash"); break; case 'R': if (REC_D != '\n') usage("multiple record delimiters"); REC_D = *optarg; if (REC_D == '\n') break; if (optarg[1] != '\0') { char *ep; int t = 0; if (optarg[0] == '\\') optarg++, t = 8; REC_D = (int)strtol(optarg, &ep, t); if (*ep != '\0' || REC_D < 0 || REC_D >= (int)__arraycount(d_mask)) errx(2, "invalid record delimiter %s", optarg); } d_mask['\n'] = d_mask[' ']; d_mask[REC_D] = REC_D_F; break; case 'T': /* -T tmpdir */ tmpdir = optarg; break; case 'u': UNIQUE = 1; break; case '?': default: usage(NULL); } } if (UNIQUE) /* Don't sort on raw record if keys match */ posix_sort = 0; if (cflag && argc > optind+1) errx(2, "too many input files for -c option"); if (argc - 2 > optind && !strcmp(argv[argc-2], "-o")) { outpath = argv[argc-1]; argc -= 2; } if (mflag && argc - optind > (MAXFCT - (16+1))*16) errx(2, "too many input files for -m option"); for (i = optind; i < argc; i++) { /* allow one occurrence of /dev/stdin */ if (!strcmp(argv[i], "-") || !strcmp(argv[i], _PATH_STDIN)) { if (stdinflag) warnx("ignoring extra \"%s\" in file list", argv[i]); else stdinflag = 1; /* change to /dev/stdin if '-' */ if (argv[i][0] == '-') { static char path_stdin[] = _PATH_STDIN; argv[i] = path_stdin; } } else if ((ch = access(argv[i], R_OK))) err(2, "%s", argv[i]); } if (fldtab[1].icol.num == 0) { /* No sort key specified */ if (fldtab[0].flags & (I|D|F|N|L)) { /* Modified - generate a key that covers the line */ fldtab[0].flags &= ~(BI|BT); setfield("1", &fldtab[++fld_cnt], fldtab->flags); fldreset(fldtab); } else { /* Unmodified, just compare the line */ SINGL_FLD = 1; fldtab[0].icol.num = 1; } } else { fldreset(fldtab); } settables(); if (optind == argc) { static const char * const names[] = { _PATH_STDIN, NULL }; filelist.names = names; num_input_files = 1; } else { filelist.names = (const char * const *) &argv[optind]; num_input_files = argc - optind; } if (cflag) { order(&filelist, fldtab); /* NOT REACHED */ } if (!outpath) { toutpath[0] = '\0'; /* path not used in this case */ outfile = outpath = toutpath; outfp = stdout; } else if (lstat(outpath, &st) == 0 && !S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { /* output file exists and isn't character or block device */ struct sigaction act; static const int sigtable[] = {SIGHUP, SIGINT, SIGPIPE, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, 0 }; int outfd; errno = 0; if (access(outpath, W_OK)) err(2, "%s", outpath); (void)snprintf(toutpath, sizeof(toutpath), "%sXXXXXX", outpath); if ((outfd = mkstemp(toutpath)) == -1) err(2, "Cannot create temporary file `%s'", toutpath); (void)atexit(cleanup); act.sa_handler = onsignal; (void) sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART | SA_RESETHAND; for (i = 0; sigtable[i]; ++i) /* always unlink toutpath */ sigaction(sigtable[i], &act, 0); outfile = toutpath; if ((outfp = fdopen(outfd, "w")) == NULL) err(2, "Cannot open temporary file `%s'", toutpath); } else { outfile = outpath; if ((outfp = fopen(outfile, "w")) == NULL) err(2, "output file %s", outfile); } if (mflag) fmerge(&filelist, num_input_files, outfp, fldtab); else fsort(&filelist, num_input_files, outfp, fldtab); if (outfile != outpath) { if (access(outfile, F_OK)) err(2, "%s", outfile); /* * Copy file permissions bits of the original file. * st is initialized above, when we create the * temporary spool file. */ if (lchmod(outfile, st.st_mode & ALLPERMS) != 0) { err(2, "cannot chmod %s: output left in %s", outpath, outfile); } (void)unlink(outpath); if (link(outfile, outpath)) err(2, "cannot link %s: output left in %s", outpath, outfile); (void)unlink(outfile); toutpath[0] = 0; } exit(0); }
int main() { int i, num; FILE *infp, *outfp; float rn, stretch = 4095.0f, *pin; /* input file open */ if (!(infp = fopen("q2input.txt", "w"))) { printf("can't open input file\r\n"); return 0; } /* write the number to input file */ fprintf(infp, "%d\r\n", RNUM); /* generate seed */ srand(time(NULL)); /* generate random number and write to input file */ for (i=0 ; i<RNUM ; i++) { rn = (float)rand()/(float)RAND_MAX*stretch; fprintf(infp, "%f\r\n",rn); } /* input file close */ fclose(infp); /* open input file */ if (!(infp = fopen("q2input.txt", "r"))) { printf("can't open input file\r\n"); return 0; } /* open output file which will store the sorted number */ if (!(outfp = fopen("q2output.txt", "w"))) { printf("can't open output file \r\n"); fclose(infp); return 0; } /* get the number of input */ fscanf(infp, "%d", &num); /* memory allocation */ pin = (float *)malloc(sizeof(float) * num); /* get the input random number */ for (i=0 ; i<num ; i++) { fscanf(infp, "%f", &pin[i]); } /* sort the input numbers in ascending order */ fsort(pin, num); /* write number to output file*/ fprintf(outfp, "%d\r\n", num); /* write it to output file*/ for(i=0 ; i<num ; i++) { fprintf(outfp, "%f\r\n", pin[i]); } /* memory free and file close */ free(pin); fclose(infp); fclose(outfp); return 1; }
void fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp, struct field *ftbl) { u_char *weights, **keypos, *bufend, *tmpbuf; static u_char *buffer, **keylist; static size_t bufsize; int ntfiles, mfct = 0, total, i, maxb, lastb, panic = 0; int c, nelem; long sizes[NBINS+1]; union f_handle tfiles, mstart = {MAXFCT-16}; int (*get)(int, union f_handle, int, RECHEADER *, u_char *, struct field *); RECHEADER *crec; struct field tfield[2]; FILE *prevfp, *tailfp[FSORTMAX+1]; memset(tailfp, 0, sizeof(tailfp)); prevfp = outfp; memset(tfield, 0, sizeof(tfield)); if (ftbl[0].flags & R) tfield[0].weights = Rascii; else tfield[0].weights = ascii; tfield[0].icol.num = 1; weights = ftbl[0].weights; if (buffer == NULL) { bufsize = BUFSIZE; if ((buffer = malloc(bufsize)) == NULL || (keylist = calloc(MAXNUM, sizeof(u_char *))) == NULL) err(2, NULL); } bufend = buffer + bufsize - 1; if (binno >= 0) { tfiles.top = infiles.top + nfiles; get = getnext; } else { tfiles.top = 0; if (SINGL_FLD) get = makeline; else get = makekey; } for (;;) { memset(sizes, 0, sizeof(sizes)); c = ntfiles = 0; if (binno == weights[REC_D] && !(SINGL_FLD && ftbl[0].flags & F)) { /* pop */ rd_append(weights[REC_D], infiles, nfiles, prevfp, buffer, bufend); break; } else if (binno == weights[REC_D]) { depth = 0; /* start over on flat weights */ ftbl = tfield; weights = ftbl[0].weights; } while (c != EOF) { keypos = keylist; nelem = 0; crec = (RECHEADER *) buffer; while ((c = get(binno, infiles, nfiles, crec, bufend, ftbl)) == 0) { *keypos++ = crec->data + depth; if (++nelem == MAXNUM) { c = BUFFEND; break; } crec = (RECHEADER *)((char *)crec + SALIGN(crec->length) + sizeof(TRECHEADER)); } /* * buffer was too small for data, allocate * a bigger buffer. */ if (c == BUFFEND && nelem == 0) { bufsize *= 2; tmpbuf = realloc(buffer, bufsize); if (!tmpbuf) err(2, "failed to realloc buffer"); crec = (RECHEADER *) (tmpbuf + ((u_char *)crec - buffer)); buffer = tmpbuf; bufend = buffer + bufsize - 1; continue; } if (c == BUFFEND || ntfiles || mfct) { /* push */ if (panic >= PANIC) { fstack[MAXFCT-16+mfct].fp = ftmp(); if (radixsort((const u_char **)keylist, nelem, weights, REC_D)) err(2, NULL); append(keylist, nelem, depth, fstack[ MAXFCT-16+mfct].fp, putrec, ftbl); mfct++; /* reduce number of open files */ if (mfct == 16 ||(c == EOF && ntfiles)) { fstack[tfiles.top + ntfiles].fp = ftmp(); fmerge(0, mstart, mfct, geteasy, fstack[tfiles.top+ntfiles].fp, putrec, ftbl); ntfiles++; mfct = 0; } } else { fstack[tfiles.top + ntfiles].fp= ftmp(); onepass(keylist, depth, nelem, sizes, weights, fstack[tfiles.top+ntfiles].fp); ntfiles++; } } } get = getnext; if (!ntfiles && !mfct) { /* everything in memory--pop */ if (nelem > 1) { if (STABLE) { i = sradixsort((const u_char **)keylist, nelem, weights, REC_D); } else { i = radixsort((const u_char **)keylist, nelem, weights, REC_D); } if (i) err(2, NULL); } append(keylist, nelem, depth, outfp, putline, ftbl); break; /* pop */ } if (panic >= PANIC) { if (!ntfiles) fmerge(0, mstart, mfct, geteasy, outfp, putline, ftbl); else fmerge(0, tfiles, ntfiles, geteasy, outfp, putline, ftbl); break; } total = maxb = lastb = 0; /* find if one bin dominates */ for (i = 0; i < NBINS; i++) if (sizes[i]) { if (sizes[i] > sizes[maxb]) maxb = i; lastb = i; total += sizes[i]; } if (sizes[maxb] < max((total / 2) , BUFSIZE)) maxb = lastb; /* otherwise pop after last bin */ fstack[tfiles.top].lastb = lastb; fstack[tfiles.top].maxb = maxb; /* start refining next level. */ get(-1, tfiles, ntfiles, crec, bufend, 0); /* rewind */ for (i = 0; i < maxb; i++) { if (!sizes[i]) /* bin empty; step ahead file offset */ get(i, tfiles, ntfiles, crec, bufend, 0); else fsort(i, depth+1, tfiles, ntfiles, outfp, ftbl); } if (lastb != maxb) { if (prevfp != outfp) tailfp[panic] = prevfp; prevfp = ftmp(); for (i = maxb+1; i <= lastb; i++) if (!sizes[i]) get(i, tfiles, ntfiles, crec, bufend,0); else fsort(i, depth+1, tfiles, ntfiles, prevfp, ftbl); } /* sort biggest (or last) bin at this level */ depth++; panic++; binno = maxb; infiles.top = tfiles.top; /* getnext will free tfiles, */ nfiles = ntfiles; /* so overwrite them */ } if (prevfp != outfp) { concat(outfp, prevfp); fclose(prevfp); } for (i = panic; i >= 0; --i) if (tailfp[i]) { concat(outfp, tailfp[i]); fclose(tailfp[i]); } }