void build_kdtree(kdxptr kd, int nbucket) { int k, n, i, d, m, j, ct; kdnode *ntab; n = kd->ngas; k = 1; while (n > nbucket) { n = n>>1; k = k<<1; } kd->nnode = k<<1; kd->nsplit = k; ntab = kd->ntab = (kdnode *) allocate(kd->nnode * sizeof(kdnode)); ntab[KDROOT].first = 0; /* initialize root node */ ntab[KDROOT].last = kd->ngas-1; ntab[KDROOT].bnd = kd->bnd; i = KDROOT; ct = KDROOT; SetNext(ct); for ( ; ; ) { /* loop splitting nodes */ if (i < kd->nsplit) { d = 0; /* find longest dimension */ for (j=1; j<3; ++j) { if (ntab[i].bnd.maxb[j]-ntab[i].bnd.minb[j] > ntab[i].bnd.maxb[d]-ntab[i].bnd.minb[d]) d = j; } m = median_index(kd->bptr, d, ntab[i].first, ntab[i].last); ntab[i].dim = d; ntab[i].split = Pos(kd->bptr[m])[d]; ntab[Lower(i)].bnd = ntab[i].bnd; ntab[Lower(i)].bnd.maxb[d] = ntab[i].split; ntab[Lower(i)].first = ntab[i].first; ntab[Lower(i)].last = m-1; ntab[Upper(i)].bnd = ntab[i].bnd; ntab[Upper(i)].bnd.minb[d] = ntab[i].split; ntab[Upper(i)].first = m; ntab[Upper(i)].last = ntab[i].last; i = Lower(i); } else { ntab[i].dim = -1; SetNext(i); if (i == ct) break; } } upward_pass(kd, KDROOT); }
//k[0,1,2,3...] int select_kth_smallest(const int *A, int len, int k) { int *medians, *tempA, *tempAA; int groupCount; int lastGroupElementCount; int i, j, median; int pivotElem; pivot_t pivot; //pivot_t span; if (len <= 1) { return A[0]; } if (len % SELECTGROUPCOUNT == 0) { groupCount = len / SELECTGROUPCOUNT; lastGroupElementCount = SELECTGROUPCOUNT; } else { groupCount = len / SELECTGROUPCOUNT + 1; lastGroupElementCount = len % SELECTGROUPCOUNT; } medians = (int*)malloc(sizeof(int) * groupCount); tempA = (int*)malloc(sizeof(int) * len); memcpy(tempA, A, sizeof(int) * len); j = 0; for (i=0; i<groupCount-1; i++) { int start = i * SELECTGROUPCOUNT; insertion_sort(tempA, start, start+SELECTGROUPCOUNT); median = tempA[median_index(SELECTGROUPCOUNT) + start]; medians[j++] = median; } // for last group insertion_sort(tempA, i * SELECTGROUPCOUNT, lastGroupElementCount); median = tempA[median_index(lastGroupElementCount) + i * SELECTGROUPCOUNT]; medians[j] = median; pivotElem = select_kth_smallest(medians, groupCount, median_index(groupCount)); pivot = median_partition_equal(tempA, 0, len, pivotElem); if (medians) { free(medians); medians = NULL; } if (k >= pivot.q && k < pivot.t) { i = tempA[pivot.q]; if(tempA) { free(tempA); tempA = NULL; } return i; } else if (k >= pivot.t) { tempAA = malloc(sizeof(int) * (len - pivot.t)); memcpy(tempAA, tempA+pivot.t, sizeof(int) * (len-pivot.t)); if (tempA) { free(tempA); tempA = NULL; } i = select_kth_smallest(tempAA, len-pivot.t, k-pivot.t); if (tempAA) { free(tempAA); tempAA = NULL; } return i; } else { tempAA = malloc(sizeof(int) * (pivot.q)); memcpy(tempAA, tempA, sizeof(int) * (pivot.q)); if (tempA) { free(tempA); tempA = NULL; } i = select_kth_smallest(tempAA, pivot.q, k); if (tempAA) { free(tempAA); tempAA = NULL; } return i; } }