static kdnode * build(kdtree *tree, int depth, double bx0, double bx1, double by0, double by1, int l, int u, double *x, double *y) { int m, i; kdnode *p = MALLOC(1, kdnode); p->empty = false; depth++; if (u-l+1 <= BUCKET_CUTOFF) { p->bnds_available = false; p->bucket = 1; p->lopt = l; p->hipt = u; for (i = l; i <= u; i++) { tree->bucket_ptr[tree->perm[i]] = p; } } else { if (depth % BNDSLEVEL) { p->bnds_available = false; } else { p->bnds_available = true; p->bnds_x[0] = bx0; p->bnds_x[1] = bx1; p->bnds_y[0] = by0; p->bnds_y[1] = by1; } p->bucket = 0; p->cutdim = findmaxspread(tree, l, u, x, y); m = (l + u) / 2; assert(p->cutdim == 0 || p->cutdim == 1); if (p->cutdim == 0) { select_rs(tree->perm, x, l, u, m); p->cutval = x[tree->perm[m]]; p->loson = build(tree, depth, bx0, p->cutval, by0, by1, l, m, x, y); p->hison = build(tree, depth, p->cutval, bx0, by0, by1, m + 1, u, x, y); } else { select_rs(tree->perm, y, l, u, m); p->cutval = y[tree->perm[m]]; p->loson = build(tree, depth, bx0, bx1, by0, p->cutval, l, m, x, y); p->hison = build(tree, depth, bx0, bx1, p->cutval, by1, m + 1, u, x, y); } p->loson->father = p; p->hison->father = p; } return p; }
struct kdnode *build_kd(struct perm_pt *p_pts, int l, int u) { int cutoff = 20; int m; struct kdnode *p; p = (struct kdnode *) ckalloc(sizeof(struct kdnode)); if( u-l+1 <= cutoff ) { p->bucket = 1; p->lopt = l; p->hipt = u; p->loson = NULL; p->hison = NULL; } else { p->bucket = 0; p->cutdim = findmaxspread(p_pts, l, u); if( p->cutdim == 1 ) quick_sort_plist_x(p_pts, l, u); else if( p->cutdim == 2 ) quick_sort_plist_y(p_pts, l, u); m = (l + u) / 2; m = adjust_m(p_pts, l, u, m, p->cutdim); p->cutval = px(p_pts, m, p->cutdim); if( p->cutdim == 1 ) { p->loson = build_kd(p_pts, l, m-1); p->hison = build_kd(p_pts, m+1, u); } else { p->loson = build_kd(p_pts, l, m-1); p->hison = build_kd(p_pts, m+1, u); } } return p; }