Hcqulslmns ana nqulstwns et Bibliographie Services services bibliographiques 395 Wellington Street 395, rue Wellington Ottawa ON KIA ON4 Ottawa ON KIA ON4 Canada Canada Your file Votre réference

Our file Notre reldrence

The author has granted a non- L'auteur a accordé une licence non exclusive licence allowing the exclusive permettant a la National Libraq of Canada to Bibliothèque nationale du Canada de reproduce, loan, distribute or sell reproduire, prêter, distribuer ou copies of this thesis in microforni, vendre des copies de cette thèse sous paper or electronic formats. la forme de microfiche/film, de reproduction sur papier ou sur format électronique.

The author retains ownership of the L'auteur conserve la propriété du copyright in this thesis. Neither the droit d'auteur qui protège cette thèse. thesis nor substantial extracts fiom it Ni la thèse ni des extraits substantiels may be printed or othexwise de celle-ci ne doivent être imprimés reproduced without the author's ou autrement reproduits sans son permission. autorisation. A new dynamic k-d (supporting insertion and deletion) labeled the k-d Search Skip List is developed and analyzed. The time for k-d semi-infinite range search on n k-d data points without space restriction is shown to be SZ(k1og n) and O(kn + kt), and there is a space-time trade-off represented as

(log T' + log log n) = Sà(n(1og n)"e), where 0 = 1 for k =2, 0 = 2 for k 23, and T' is the scaled query time. The dynamic update tirne for the k-d Search Skip List is O(k1og a). We consider the problem of reporting al1 points in a positive half-space h* (bounded by a query hyper plane h) fiom a F of n points in k-dimensional space EL;that is, find and report Snh*. Previous dynamic solutions (supporting insertion and deletion of points) are simplified, and the previously best known dynamic update time is irnproved. For t = $n h' [ we show that with O(Rn1og n) preprocessing time and 8(b)space, the k-d half- space searching problem can be solved in O(kn)time with dynamic update time of O(k1og 4. Experimentally for a random data set of 100,000 points, an average of 1048 milliseconds was required to report 50,000 points in range for a 10-d orthogonal range search; about 800 milliseconds was required to report 50,000 points in range for a 10-d semi-infmite range search; and 106 milliseconds was required to report 50,000 in range for a 1O-d half-space range search. First 1 would like to express my sincere thanks and appreciation to my supervisor, Dr. Bradford G. Nickerson, for his suggestion of this specific topic, invaluable guidance and encouragement concerning my academic and nonacademic endeavours. Through weekly discussions, his efforts made it possible to fonn a solid basis for my thesis, and for this 1 am grateful. 1 would like to thank the readers, Dr. Joseph Horton, Dr. B. Spencer, and Dr. D.Smal1, whose valuable comrnents improved the overall presentation of the work. I thank Michael G. Lamoureux for his valuable comments and insightful advice. And finally, a thank you is extended to the Faculty of Cornputer Science whose continua1 funding made this work possible. ABSTRACT...... ii ACKNOWLEDGEMENTS...... iii LISTOFFIGURES...... iv LIST OF TABLES...... v LISTOFALGORITHMS...... vi Chapter 1 INTRODUCTION...... 1 1.1 Definition ...... 2 1.2 Objectives ...... 5 Chapter 2 DATA STRUCTURES FOR POINT DATA RANGE SEARCHING. . 7 2.1 1-Dimensional Data Structures ...... 7 2.2 k-Dimensional Data Structures ...... 8 2.2.1 The Range ...... -10 2.2.2 The Priority Search Tree ...... -13 2.2.3 The Range Priority Tree ...... -14 2.2.4 k-d Skip Lists ...... -16 2.2.4.1 2-d Search Skip List ...... 17 2.2.5 k-d Range Deterministic Skip List...... 18 Chapter 3 THE K-D SEARCH SKIP LIST ...... -22 3.1 ~efinitionof a k-d ~earchskip ~ist...... 22 3.2 Description of Implementation Design ...... 24 3.3 Building a k-d Search Skip List ...... 30 3.4 Insertion in a k-d Search Skip List ...... 30 3.5 Range Search for a k-d Search Skip List ...... 35 3.6 Serni-infmite Range Search in k-d Search Skip List ...... 38 3.7 Deletion in a k-d Search Skip List ...... 43 Chapter 4 LOWER BOUNDS ...... 47 4.1 No Space Restriction ...... 48 4.2 With Space Restriction ...... 49 Chapter 5 HALF-SPACE RANGE SEARCH ...... -52 5.1 Half-Space Range Search in the Planar Case ...... 54 5.1.1 The Half-Space Range Search Algorithm ...... 54 5.1.2 Analysis of The 2-d Search Skip List ...... 57 5.2 ~alfS~aceRange Search in Ek,when k > 2 ...... 58 5.2.1 The Half-Space Range Search Algorithm ...... 58 5.2.2 Analysis of the k-d Search Skip List ...... 65 Chapter 6 EXPERIMENTAL RESULTS ...... 67 6.1 k-d Range Search and Semi-Infinite k-d Range Search...... 67 6.2 An Analysis of the k-d Search Skip List ...... 76 6.3 k-d Half-Space Range Search ...... 81 Chapter 7 CONCLUSIONS ...... 85 ...... Ud 7.2 Future Work ...... 86 REFERENCES ...... 88 Appendix A: Raw Construction and Destruction Time for Testing the k-d Search Skip List ...... 91 Appendix B: Average Construction and Destruction Time for Each Test Run of the k-d Search Skip List ...... 112 Appendix C: Raw Insertion and Deletion Constant for Testing the k-d Search Skip List ...... 118 Appendix D: Insertion and Deletion Constant for Each Test Run of the k-d Search Skip List ...... -139 Appendix E: Average Search Time for Each Test Run of the k-d Search Skip List ...... 145 Appendh F: Half-Space Range Search Time for Each Test Run ...... 153 Appendix G: Average Search Time for Half-Space Search ...... -172 Appendix H: Complete Source Code for the Test Drive Routines for the k-d Search Skip List and Haif-Space Range Search ...... -174 Hl Makefile for the k-d Search Skip List and Half-Space Range Search . -175 H2 The File "kdskiplist.h"...... 176 H3 The Fie Lbkdskiplist.cc"...... 179 H4 The File Lbhskdlist.h"...... -197 HS The File bLhskdlist.cc"...... 200 H6 The File Lbkdtest.cc"...... 217 Figure 1.1 In E', the line h and the positive halfspace h*

Figure 2.1 (a) A 1-d range tree (fkom Samet[ 1990))

Figure 2.1 (b) A 2-d range tree (from Samet[1990])

Figure 2.2 A priority search tree (from Sarnet [1990])

Figure 2.3 A 2-d range priority tree (frorn Sarnet [1990])

Figure 2.4 A 2-d search skip list (from Nickerson [1994])

Figure 2.5 (a) The Range DSL structure in dimension 1 (ordered on K,)

Figure 2.5 (b) The Range DSL structure "A" (ordered on K,)

for a 2-d range DSL (from Lamoureux [1996]) 20

Figure 2.5 (c) The Range DSL structrues "B","C', & "D (ordered on K2)

for a 2-d range DSL (fiom Lamoureux [1996])

Figure 3.1 Composition of a single node in a k-d search skip list

Figure 3.2 A 2nd search skip list (order on K,)

Figure 3.3 Aggregation between class KDSSkipNode and class KDSSkipList

Figure 3.4 (a) The data memben of the class KDSSkipNode

Figure 3.4 (b) The description of the member functions of class KDSSkipNode

Figure 3.5 (a) The data members of the class KDSSkipList

Figure 3.5 (b) The descriptioii of the member functions of the class KDSSkipList

Figure 3.6 Illustration of worst case for 2-d range search with a 2-d search skip list

Figure 3.7 Illustration of no data point in the 2-d up semi-infinite search region Search Skip List or order 3

Figure 5.1 Modified composition of a single node in a k-d

Search Skip List to allow half-space range search 52

Figure 5.2 Sample modified k-d Search Skip List 53

Figure 5.3 Half-space range search for the 2-dimensional Search Skip List 54

Figure 5.4 Illustration of worst case for 2-d half-space with a k-d Search Skip List 66

Figure 6.1 The query window of 2-d semi-infinite range search 70

vii Table 1 The value of (nklog n)/100,000 for different tests 72

Table 2 Construct time averages for al1 mns of testing the k-d Search Skip List 76

Table 3 Destruct time averages for al1 runs of testing the k-d Search Skip List 77

Table 4 Average insertion constants for al1 nins of testing the k-d Search Skip List 77

Table 5 Average deletion constants for al1 runs of testing the k-d Search Skip List 77

Table 6 The average orthogonal search time (milliseconds)

for the k-d Search Skip List

Table 7 The average semi-infînite range search time (milliseconds)

for the k-d Search Skip List

Table 9 The average half-space range search time (milliseconds)

for the k-d Search Skip List

viii Algorithm 3.1 Summary of insertion steps in a k-d Search Skip List

Algorithm 3.2 Insertion on a k-d Search Skip List

Algorithrn 3.3 Range search for a k-d Search Skip List

Algorithm 3.4 Up semi-infinite range search for a k-d Search Skip List

Algorithm 3.5 Up semi-infinite range search pseudo-code forrn for a

k-d Search Skip List 40

Algorithm 3.6 Summary of deletion steps in a k-d search skip list 44

Algorithm 3.7 Deietion fiom a k-d Search Skip List 45

Algorithm 5. i C++ pseudo-code algorithm for k-d half-space range search 64

Algorithrn 6.1 Random query window generation 69

Algorithm 6.2 (a) Main driver routine for testing the k-d Search Skip List 74

Algorithni 6.2 (b) Sub- driver routines for testing the k-d Search Skip List 75

Algorithrn 6.3 (a) Main driver routine for testing half-space range search algorithm 82

Algorithm 6.3 (b) Sub-driver routines for testing half-space range search algorithm 83 Lnapter 1 INTRODUCTION

Multi-attribute data can be referred to as multi-dimensional (or k-d) data as each amibute cm be viewed as a separate dimension of a k-dimensional space. The capability to

store, retrieve and search for k-d data is a fundamental component of many computer

information systems. The problem of k-d range search is important in itself (having

applications in such areas as computer graphies, database management systems,

computational geometry, pattern recognition, statistics, design automation, and geographic

information systerns). In addition, k-d range search serves as a representative of the entire

class of multi-attribute searching problems.

The problem is not as obvious as it may first seem. The collection of records may be

preprocessed to achieve a balance between the storage utilized and the time required to

answer a query. There is an extensive literature (e.g. Bentley and Fredman [1979]) on

algoriths for range query, and the space and time requirements have traditionally been used

as performance measures for such algorithms. We also know there is a (storage) space -

(retrieval) time tradeoff for orthogonal range search on a static database [Vaidya, 19891.

Today's applications require a dynamically updatable database and thus any index stmcture

for the database must also allow fast dynamic updates to ensure feasibility. These

interdependent requirements imply that the design of a dynamic data structure for efficient

k-d range search is difficult and ofien unintuitive.

Upper bounds on the worst case search time, update operations, and storage

1 ------i--- A"- .--1. L L Y."..+ bu requirement of 0(n2) is excessive for large n, where n is the nurnber of data points in the structure, or there may not be enough storage space for the structure when the data set is large. The k-d range search time must be O(kn), otherwise the structure provides no improvement over an unstructured brute force search. The sarne holds true for the time required for dynamic updates; otherwise the structure would have tu be rebuilt with each

insertion and deletion and such a structure is not considered dynamic.

Implementable structures do exist which provide for efficient k-d range search in a

dynarnic environment. These include dynarnizations of the k-d range tree of Bentley[1980a]

and the k-d Range Deterministic Skip List (k-d Range DSL) of Lamoweux[l996]. Although

efficient, they do not meet the lower bound of P(k log n + t) for range search provided by

the decision tree model.

1.1 Definitions

Range searching is an oid-age problem in cornputer science. We can phrase range

searching in geometric terms; i.e. given a set F of n points in k-d space, we preprocess these

points into a data structure. After we have preprocessed the points we must answer queries

which ask for al1 points x of F such that the first coordinate of x(xl) is in some range [LI:

H,], the second coordinate x7 E IL2: HI], ..., and xk E CLk:Hk]. We also can phrase this

problem in the terminoiogy of data bases; i.e. given a file F of n records, each having k keys,

process this file into a database that enables storage, retrieval and range search on the - u X---J -'--0'-0' (SQL)) asking for al1 records such that the first key is in some specified range, the second key in a second range, etc. Boolean combinations of range queries over different attributes are called orthogonal range queries. A range search is performed to retneve the records specified in the query. The intersection of the query ranges is a k-dimensional hyperrectangle in the space (that is, a "box"), and a range query calls for finding ail points lying inside this hyperrectangle.

To motivate this problem, the classical scenario is to regard the points of S as the employees of a certain company. The coordinates of the points are important attributes of

the emplyees, such as seniority, age, salary, traveling assignrnents, and legal statu. Crucial

to the proper fûnctioning of the company is the ability to provide fast answers to questions

of the fom: "Which senior-level employees are less than x years of age, make more than y

dollars a year, have been abroad in the Zast z months, and have never been convicted of a

Criminal Code ofense? ". We will often cast range searching in this geometric framework

as an aid to intuition.

Semi-infinite range search asks for al1 records with key values each within either the

([LI: Hl], IL7: m), ..., ILk: 00) ), or the ([L,: H,], ( -=: LJ, ..., (- =: Lk]) mode. We cal1 these

the "Up semi-infinite range search" and "Dom semi-infinite range search", respectively.

When the conjunction of k semi-infinite range queries on different attributes is required, we

cm view each separate attribute as one dimension of a k-dimensional space, and the semi-

infinite range search corresponds to asking for al1 records (data points) that lie within a k-

dimensional (hyper) rectangular box with (k-1) iine segments as boundaries of the data

3 For obvious reasons, this is called range searching in report-mode, or more simply, range reporting. To put this problem in perspective, range reporting refers to the task of reporting al1 the points that fa11 in the searching region. Evaluating the number of the points falling into the search region is called range counting. Unless noted otherwise, range reporting is assumed. This implies that rnany of our LI, O, and O analyses of the range search cost functions will have an extra term of t which captures the tirne needed to report the t records in range.

Five functions normally portray the cost for range searching on a specific data

structure G that supports range search and dynamic operations on F. They are

P(n, k) = preprocessing time required to build G,

S(n, k) = storage space required by G,

Q(n, k) = time required to perform a range search,

as defined in Bentley [1979]. In addition, we also consider the time required to insert a point

into or delete a point fiom G as we are permitting dynarnic updates on our structure. The

cost of these dynamic operations are represented by

I(n, k) = time required to insert a new record in G,

D(n, k) = time required to delete a record from G.

For k> 1, let Ek denote k-dimensional Euclidean space. We use h* to denote one of

the two open halfspaces bounded by a hyperplane h in EL.An open halfspace h* is called

positive if either h is vertical or h* is the open half-space above h, Le., h* intersects the

positive vertical axis in a half-line [Haussler, 19871. A halfspace range search is defined as:

4 ------vrirv..brrib LW wru rviiii 1 i II\, WllClC fi IS an open halfspace. For example, given a set F of n points in E2 and a query hyperplane h, the halfspace range search problem asks for the retrieval of al1 points of F on a chosen side of h (see Figure 1.1).

h* (positive)

h

Figure 1.1 In E~,the line h and the positive halfspace h*.

1.2 Objectives

The objectives of this thesis are stated as follows:

For a set F of n points in k dimensions,

1. review and analyze data structures that permit k-dimensional range search; determine the asymptotic running times in the worst case;

3. determine the worst case for the semi-infinite range search using a k-d Search Skip

List;

4. determine the lower bound for semi-infinite range search of k-d data points, either

with or without restriction on the space required for the data structure;

5. determine if the k-d Search Skip List can be adapted to half-space range search;

6. perfonn an experimental verification of the results with large (e.g. n = 1OS) randomly

generated data sets.

In the pages that foilow, each of the objectives is addressed and an attempt is made

to summarize and unite much of the relevant work in this area. The asyrnptotic running

times in the worst case for the k-d Search Skip List are determined, and it is shown that the

k-d Search Skip List meets the lower bounds for semi-infinite range search. Also, the k-d

Search Skip List is adapted to half-space range search. An experimental analysis of the k-d

Search Skip List was performed and the results are illustrated and compared in Chapter 6. V ..-- r---- DATA STRUCTURES FOR POINT DATA RANGE SEARCH

This thesis focuses on data structures for orthogonal range queries as defined by

Knuth [ 19731, semi-infinite range search as defined by McCreight [ 19851 and half-space range search as defined by Chazelle and Preparata [1986]. Data structures and algorithms that support other types of range queries cm be found in the excellent survey paper of

Matousek [1994] which illustrates many problems which are of great importance in the field of computational geometry.

2.1 1-Dimensional Data Structure

We first illustrate 1-dimensional data structures that permit range search, as many

of the existing k-dimensional structures are based on rnulti-dimensional equivalents of

efficient 1-dimensional data stxuctures.

The simplest 1 -dimensional data structure for range search is the unsorted list which

permits a brute force range search of O(n) . The list cm be sorted to allow

for a range search tirne complexity of 8(lg n + t), which is executed by performing one

binary search (to locate the flrst point in range) and listing al1 points in range.

One may also use a multi-way height balanced search tree known as the B-tree, of

which a good overview may be found in Corner [1979], which allows for a worst case range

search in time @(lg ,n + t) (where m is the order of the B-tree), or a deterministic skip list complexity.

2.2 k-Dimensional Data Structures

Although there are many data structures which facilitate rapid average query tirne in k-dimensions, we fînd that there are relatively few which exhibit good worst case behavior. In cornparison to the 1-dimensional case, there are simple, inefficient stmctures that one may use to execute a k-d range search. These include the unsorted list, which requires O(kn) tirne to perform a range search, inverted tables, which are composed of k sorted lists on each of the coordinates and which require O(kn) time to perfôrm a range search in the worst case (but often require less time in the average case), and cells, which divide the space up into a number of "boxes" or "blocks" which are searched separately if they are partially (or totally) within the desired search range. Cells are no better than

inverted tables for range search in the worst case, but are often better in the average case.

The reader is referred to Bentley [1979] for a more detailed overview of these structures.

Another simple, inefficient approach is that of the multidimensional B-tree of Guting

and Knegel[1980]. Designed specifically for exact match (member) queries, it is no better

than inverted tables for range search in the worst case but may exhibit good average case

performance for uniformly distributed random data sets.

A more sophisticated approach is that of the k-d tree of Bentley [1975] which is the

multidimensional equivalent of the . Although no better than inverted - - , --- .. W.Y. Lu YI\UIILAL,,ly QJLU 13 U~NI LI wniçn is guaranteed to be the worst case search time if the given tree structure is height balanced

(and therefore of minimal depth). The advantages of the structure are its low storage requirement, being essentially that of a binary search tree (i.e. @(lm)), and the fact that dynamic operations are almost as simple as those of the regular 1-d binary search tree. In the average case, which is the worst case for a height balanced structure, P(n, k) = O(n Ig n) and

U(n, k) = O(lg n). The drawback of the structure is that a direct implernentation does not support dynamic maintaince of height balance Samet 119901.

An approach that is sirnilar in structure, complexity, and functionality to that of the

k-d tree of BentIey 11 9751 is that of the K-D-B-Tree of Robinson [ 198 11 which combines

the k-d tree of Bentley with the B-tree (as defined in Corner 119793). Although a detailed

analysis, to the author's knowledge, does not exist in the literature, experirnental results

indicate that its efficiency parallels that of the k-d tree.

A good overview of data structures for range searching can be found in

Bentley et al [1979]. The point quadtree of Samet [1990] may also be used for

multidimensional range search and, under the strong assumption of relatively evenly spaced

data, has a worst case range search time of O(kn l-'Ik + t ) which is comparable to that of the

k-d tree.

We examine k-d structures that allow for a more efficient (guaranteed) worst-case

search time in the sections that follow. u ---

The range tree of Bentley and Maurer [1980] is a rnodified height-bafanced binary search tree which is designed to detect al1 points that lie in a given range. We briefly review the range tree data structure and refer the reader to Sarnet [ 19901 for a more comprehensive

ovewiew.

The 1-dimensional range tree (see Figure 2.1 (a)) is a height balanced binary search

tree where the data points are stored in the leaf nodes which are linked in sorted order by a

doubly (the leaf nodes are threaded). A range search for [L:H] is perforrned by

searching the tree for the node with the smallest key r L and then following the links untii

reaching ô ieaf node with a key that is greater than or equal to H. For n points, we see that

this procedure takes O(lg n + t) time and uses Q(n) storage.

A 2-dimensional range tree (see Figure 2.1 (b)) is sirnply a range tree of range trees.

We build a 2-dimensional range tree as follows: we first sort al1 of the points along one of

the attributes, x, and then store them in a balanced 1-dimensional range tree, T. We then

append to each non-leaf node, 1, of the range tree T a range tree T, of the points in the sub-

tree rooted at 1 where these points are now sorted along the other attribute, y. In Figure 2.1

(b), the darkened links connect the range tree T, (which has a primed node as root) in

dimension 2 to the (un-prime4 non-leaf node it is rooted at in dimension 1. Figure 2.1 (b) A 2-d range tree (from Samet [1990]).

A range search for ([L,:H,], [L,:H,]) is carried out a follows. It starts by searching the tree t for the smallest key that is r Lx,say Lx',and the largest key that is r H,, Say H,'.

It then finds the common ancestor of Lx' and H,', Q, that is closest to them and assigns

(PLi) and (PHi) to be the sequences of nodes, excluding Q, that forrn the paths in T from

Q to L,' and H,', respectively.

11 ---r--..-. "A **W.* . r U ------, --,, leaf node P. Then, for each P that is an element of {PLi)such that LEFT(P) is also in {PL,}, we perfom a 1-dimensional range search for [L,:H,] in the 1-dimensional range tree rooted at node RIGHT(P). For each P that is an element of {PHi) such that RIGHT(P) is also in

{PHi), we perform a 1-dimensional range search for [Ly:Hy] in the 1-dimensional range tree

rooted at node LEFT(P). We also check to see if Lx' and H,' are located in the given range.

The above search algorithm can be seen to mn in 8(lg ' n + t) time and the general

search algorithm for k-dimensional range queries, which is extended in a marner that is

analogous to the extension fiom the 1-d case to the 2-6 case, nins in O(lg n + t) time.

The recursively defined k-dimensional range tree has P(n, k) = O(n lg k-' n) and

S(n, k) = O(n lg '-' n) in the static case and has P(n, k) = 8(n lg n) , S(n, k) = $(n Ig k-l n),

and U(n, k) = 8( lg 'h) in the dynamic case where an amortized worst case analysis is used.

Dynamizations of the k-d range tree can be found in Lueker 11 9781, Willard and Lueker,

[ 19851 and, more recently, in Lamoureux [ 19961.

The range tree is important for a number of reasons. Not only is it a prime example

of the paradigm of rnulti-dimensional divide and conquer, introduced by Bentley [ 19801, but

it is also a prime example of the effective use of a class of transformations which can be

used to add range restriction to an existing data structure for a decornposable searching

problem such as range search [Bentley, 19791. Thus, we cm build it bottom up starting with

a 1-d range tree structure on the first coordinate or build it top down starting with a k-d data

set and applying the paradigm of multi-dimensional divide and conquer until we reach a 1-d

range tree structure. r rus ~CUÛUI~II~UL rriuiri-aimensional alviae and conquer States that we can solve a problem of n points in k-space by first recursively solving two problems each of n/2 points in k-space and then recursively solving one problem of n points in (k-1) space. Thus, a structure which solves a problern using the paradigrn stores two structures of n/2 points in k-space and one structure of n points in (k-1) space.

A given interior node in the range tree is the root of a subtree of m nodes. It has two children which are the root nodes of range trees that each have approximately m/2 nodes and it has a pointer to a (k- 1)-dimensional tree of m nodes. Another example of the paradigm can be found in Bentley [1979].

The theory of decomposable searching problems can be viewed as the dual of the

paradigrn of multidimensional divide and conquer. We cm add a second range variable to

a 1-d range tree structure (on one range variable) by building a range tree structure on the

new variable and attaching to it 1-d range tree structures on the first range variable.

The range tree is a balanced data structure and is optimal for the execution of range

queries in the class of baianced data structures. Also, the static range tree can be derived

from non-overlapping k-ranges, and array-based data structures.

2.2.2 The Priority Search Tree

The priority search tree of McCreight 119851 is designed for solving semi-infinite

range queries of the form ([L,: H,], [L,: -1) in optimal time. For each non-leaf node 1 of

priority search tree S, we associate the point in the subtree rooted at 1 with the maximum vaLucrui 1~3Y r;ouruinare rnar nas nor aiready been stored at a shallower depth in the tree.

It is assumed that no two data points have the same x coordinate; the reader is again referred to Samet [1990] for the details on the construction of the prionty search tree. An example of a priority search tree is found in Figure 2.2.

(5*45) (25,351 (35.40) (50.1 O) (60.75) (80.65) (85.15) (90.5)

Figure 2.2 A priority search tree (fiom Samet [1990]).

The priority search tree requires minimal storage space, having S(n, 2) = @(n) and

is optimal for semi-infmite range search in two dimensions, i.e. Q(n, 1.5) = Q(lg n + t). The

1.5 refers to the fact that only a lower or upper query limit can be specified in the second

dimension, but not both. Dynamic updates are optimal as well, requiring only 8(lg n) time

per update. However, a normal 2-d range query, Q(n, 2), requires 8(n) time in the worst

case.

The importance of the structure is that it is the bais and inspiration for the Range

Pnority (RT) tree of Edelsbrunner [198 11 and the 2-d Search Skip List of Nickerson 119941.

The Range Pnority (RT) tree Is important as it shaves off a logarithmic factor fiom the k-d

range query time of the range tree. The range priority tree, caIled the RT-tree, by Edelsbrunner [198 11 is a k-d data structure designed specifically for k-d range search and it is similar to the range tree of

Bentley. The structure is optimal for range search in two dimensions, i.e.

Q(n, 2) = O(lg n + t), and takes advantage of the priority search tree of McCreight [1985]

to achieve its optimality. An example of the range priority tree can be found in Figure 2.3.

An inverse priority search tree is a priority search tree, S, such that with each non-

leaf node, 1, of S we associate the point in the subtree rooted at 1 with the minimum value

for its y coordinate that has not already been stored at a shallower depth in the tree.

Figure 2.3 A 2-d range priority tree (from Samet [1990]).

A range priority tree is a balanced binary search tree, T, where al1 data points are

stored in the leaf nodes and are soned by their y coordinate values. With each non-leaf node

I of T which is a right child of its parent we store an inverse priority search tree of the points 111 UIG YUVUGG ruuiea ar 1 oraerea on meir x coordinate values. With each non-leaf node 1 of

T which is a left child of its parent, we store a priority search tree of the points rooted in the subtree of 1 ordered on their x coordinate values. This scheme allows us to shave off a logarithmic factor fiom the k-d range search time of the range tree for a Q(n, k) of

8(lg '"n + t) for k 22.

2.2.4 k-d Skip Lists

Nickerson [1994] has defined a number of k-d skip list data structures for k-d range

search which are built from 1-d deterministic skip lists and similar both in structure and

range query time to inverted tables. As they are not very efficient for k-d range search in the

worst case, we do no more than mention them and instead focus on Nickerson's 2-6 search

skip list as it provides an efficient aitemative to the priority search tree and is the special

case for the k-d search skip list.

A deteministic skip list is a tree-like structure which has a node structure that

contains (at least) a down pointer, a right pointer, and a data value. We use the following

ternis when describing the structure and the associated algorithms. The down subtree of a

node N consists of all nodes that can be reached by traversing the down pointer of N, except

those nodes reachable by traversing the down pointer of right sibling of N. The ZeJ subtree

of a node N at depth i is composed of al1 nodes at depth (i +1) in the down subtree of N. The

gap size is defined to be the number of nodes in the lep subtree where we exdude the direct

descendent. 1 vr cnairlpic, iu rlgurt: L-4,nore rnar M Stands tor the maximum key value, and @ stands for the non-value key. The down subtree of the node (140, 37, -30, 41) at level 1 consistsofthenodes(14,41,41,41),(31, -30,-30,-30),(104,2,2,2), and(140,37,37,37) at level O. The left subtree of the node (M, a, -34,52)at levei 2 consists of the nodes (0,52,

39,52), (140,37, -30,41), and (M, 4, -34,-34) at level 1. The direct descendent of (0,52,

39,52) at ievel 1 is (-123,48,48,48)at level0, and the gap size of (M,$, -34,-34) is 1.

2.2.4.1 2-d Search Skip List

The 2-d search skip list of Nickerson 119941 uses the idea inherent in the priority

search tree and is based on the lùiked-list version of the 1-3 deteministic skip list (DSL)of

Munro et al 119921. It is always balanced (in the sense of B-trees) as the leaves are al1

located at the sarne depth c lg n, !4 5 c 5 I. The properties of the structure are

1. Each node contains four values. These are

i) (K,, KI) = keys of the node (the two top fields in Figure 2.4)

ii) mink2 = minimum K:!value for al1 nodes in the Ieft subtree

iii) maxk2 = maximum K2 value for al1 nodes in the left subtree

2. Each node has two pointers; a down pointer and a right pointer.

3. Special nodes head, tail, and bottom indicate the start and end of list conditions.

4. Al1 data points appear at the leaf level and some may appear at higher levels.

5. Every gap size in the skip list is of size 1,2, or 3.

6. The skip list is ordered on the K, key values. is a prime example of the fact that deterministic skip lists provide efficient alternatives to

height balanced search trees as illustrated in Lamoureux [ 19961. head r~~

-34 52, 3 rtlbi tail

Figure 2.4 A 2-d search skip list (fiom Nickerson [1994]).

2.2.5 k-d Range Deterministic Skip List

The k-d Range Deterministic Skip List (or k-d Range DSL) is a data structure for

multi-dimensional point data based on an extension of the 1-3 Deterministic Skip List

projected into k-dimensions.

The properties of the structure are:

1. Each node contains a data point which is either

i) an actual data point if the node is a leaf node (K,, K,. ..., KJ, or

ii) a pre-defined sentine1 value (s.v.) if the node is not a leaf node.

2. Each node contains two values. These are

i) minki = minimum Ki value in the lefi subtree of the current node, and 3. Each node contains three pointers; a dompointer, a right pointer, and a nextdim

pointer. The down and right pointers are analogous to the dom and nght

pointers in the 1-d DSL and the nextdim pointer points to a Range DSL

structure of the points in the lefi subtree ordered on the K,,, coordinate

values.

4. Four special nodes called head, tail, bottom, and lastdim are used to indicate

start and end of structure conditions. The nodes head, tail, and bottom are

identical to the head, tail, and bottom nodes in the 1-3 DSL and the node

lastdim lets us know that we have reached the last dimension of the structure

or the leaf level.

5. Al1 data points appear at the leaf level and only at the leaf level.

6. The skip list is ordered by the i coordinate values where i represents the

dimension that is currently being built or searched (i starts at 1 and proceeds

to i= k).

7. Every gap in the skip list is of size 1,2, or 3.

The k-d Range DSL supports fast insertions and deletions which require @(logkn) arnortized time, and it requires Q(n, k) = @(logkn + t) time to perform a worst case k-d range search. It is dynamically balanced and optimal for k-d range search in the class of dynamicaIly balanced data structures. An exarnple of a 2-d range DSL can be found in

Figure 2.5. head

I S.V. I I

-124 -9 ' 0 131 1041150 M (hl 8.v. S.V. S.V. W,MI ,

I M (m S.V. lastdm

bottom

Figure 2.5 (a). The Range DSL structure in dimension 1 (ordered on KI)

for a 2-d range DSL (from Lamoureux [1996]).

A

S.V.

I

Figure 2.5 (b) The Range DSL structure "A" (ordered on Kz)

for a 2-d range DSL (from Lamoureux [ 19961). 39 148 S.V. S.V. lastdim lastdim

I

Figure 2.5 (c) The Range DSL structures "B", "C", & "D" (ordered on K?)

for a 2-d range DSL (from Lamoureux [1996]). THE K-D SEARCH SKJP LIST

The k-d Search Skip List is a new data structure for multi-dimensional point data based on a 2-d Search Skip List Nickerson [1994]. It uses the priority search tree idea. The k-d Search Skip List of order rn is based on the linked-list version of the 1-3 Detenninistic

Skip List @SL) Papadakis [ 19931. This means that it is always balanced in the sense of B-

trees; i-e. the leaves are al1 at the sarne depth of log n.

3.1 Definition of a k-d Search Skip List

A k-d Search Skip List of order m has the following properties:

1. Each node contains a data point which is an actual data point (K,, Kz, ..., K, )

2. Each node contains (2k-2) values. These are

i) minki = minimum Ki value for al1 nodes in the left subtree of the

current node, where 2 5 i < k

ii) maxki = maximum Ki value for al1 nodes in the lefi subtree of the

current node, where 2 5 i s k

3. Each node has two pointers; a dom pointer and a right pointer. The down

pointer points to the left subtree for this node. The right pointer points to

the right subtree for this node. A right subtree is defined as the right sibling

node of this node. A left subtree is defined as al1 the descendant nodes and 4. Three special nodes called head, tail and bottom are used to indicate the start

and end of list condition. The nodes head, tail and bottom are identical to the

head, tail, and bottom nodes in the 1-3 DSL.

5. Al1 data points appear at the leaf or bottom level, and some points also appear

at nodes above the bottom level.

6. Every gap size in the skip list is between Ld21 and m. Gap size is defined as

the number of elements of height h-1 that exist between two linked

elements at height h, excluding direct descendants.

7. The skip list is ordered by the K, key values.

An element (used in descnbing property 6) is a vertically stacked set of nodes linked directly by down pointers. As described in Papadakis [1993], this structure of order 3 is somewhat similar to a 2-3-4 tree. Figure 3.1 illustrates the composition of a single node, and

Figure 3.2 shows a 2-d Search Skip List of order 3.

Figure 3.1 Composition of a single node in a k-d search skip list. head

Figure 3.2 A 2-d search skip list (order on K,).

The main advantage of the k-d Search Skip List lies in the fact that it is much sirnpler

to conceptualize and implement than a dynarnic range tree structure. It has the additional

advantage that the algorithms are highIy iterative in nature. This implies that some

implementations could outperfoxm some implementations of a range tree as recursion

involves extra overhead, and therefore extra time. Also, as we usually will not have a worst-

case structure, the depth of the structure is usually iess than that of a corresponding range

tree structure and thus range searches may be faster than they would be in a range tree.

3.2 Description of implementation Design

First we look at the aggregation diagram (see Figure 3.3) of class KDSSkipNode and

class KDSSkipList. Rurnbaugh et al [1991]. A line with a small diamond is the OMT symbol for "aggregation".

Aggregation is the "part-whole" or "a-part-of' relationship in which objects representing the cornponents of something are associated with an object representing the entire assembly. The small diamond indicates the assembiy end of the relationship. A soiid bal1 is the OMT syrnbol for "rnany",meaning zero or more. That is, many instances of one ciass may relate to a single instance of another class. Therefore our diagram indicates that one instance of

KDSSkipNode class contains zero (empty Iist) or rnany instances of the KDSSkipNode

class. temple~r KDSSkipList

public: KDSSkipList(): -KDSSkipList() {clcar(): :

const KDSSkipNodc* geiHead() consi l,reiurn head;) int geihcight0 consi: int insert(consr T val[k], char* namceNULL); consr KDSSkipNode* search(consr Tg! val. long& numOfcomps1 const: void rangeSerrch(const KDSSkipNode& srartNodc. consl T minRanyc[t]. cons1 T mnxRnny[k]. const T T& rnnxFirsi. long& numfound) consr; void rangeSearchUp(const KDSSkipNode& siartNode. conrt T minRnnge[k]. consl TB: highl, //max range for x, consi T& maxfirsi, tank numfound) consi: /lup scrni-inhitc in! deleicNodc(cons~Tb v): templatc KUSSkipNadc void prinil.isi() const; private: frieiid class KDSSkipList KDSSkipNode *hcad. *bottom, *tail: private: vnid newMaxMin(KDSSkipNode& inNode); KDSSkipNodecT> 'ripht. *dinvn; lI rcset the max and min for x,. .... x, char *name: void printNodcData(conR KDSSkipNodc& node) consi: T kcys[3][k]: void printNodcMin(cons1 KDSSkipNodcb node) consr: void printNodcMan(cons KDSSkipNodr& node) cons!: void clcar(); public: KDSSkipNodeo: KDSSkipNode(consi T inKeys[k]. const charg inName): -K DSSkipNodc(); private: void setNarne(coi~stchar* narnr); void setData(cot1st T val[k]); void setMin(const T min0Ikj): void serMin(cnnst T min1 Ili). cnns! T rnin?[Ii]): void setMax(const T rnaxolk]): void sctMax(const T maxllk]. const T mal-lkl): ini isMinLcqInpui(consi 'I' inputIli]) const; int isMaxGeqliiput(const 'r iiiputlk]) consr: ini isDnlalnRanrclcons T* rninR. const T* maxR) const; hi isDaialn~a~i~e(consiTb rninR. const T & hiphl) consi: int isDatalnRange(consi T & low 1. cons! T* mexR) const;

Figure 3.3 Aggregation between class KDSSkipNode and class KDSSkipList. KDSSkipNode *right; Ilthe right pointer. KDSSkipNoderIi> *down; //the down pointer. char *name; //each node may have a name. T ke~s[3lLk]; //keys[O][]: xi, x2, ..., xk; //keys[ 1] []: minx,, minx?, .. ., minx,; //keys[2] []: maxx ,, rnaxx?,. . . , maxx,.

Figure 3.4 (a) The data members of the class KDSSkipNode.

The mernber Eunctions are (see Figure 3.4 (b)): KDSSkipNode(); //defauit constructor of KDSSkipNode. KDSSkipNode(const T inKeys[k], const char* inName); //constructor of KDSSkipNode. -KDSSkipNode(); //destructor of KDSSkipNode. private: void setNarne(const char* name); //set the name of the node. void setData(const T val[k]); //set the k key values for the node void setMin(const T minO[k]); //set the minimum values of x2, ..., x, as the input void setMin(const T min1 [k], const T min2[k]); //set the minimum values of x?, ..., x, as the minimum //of min 1[il and min2 [il. void setMax(const T maxO[k]); //set the maximum values of x?, ..., x, as the input. void setMax(const T maxl [k], const T max2[k]); //set the maximum of x?, ..., x, as the maximum //ofmax 1[il and max2 [il. int isMinLeqInput(const T inputlk]) const; //check whether al1 the mins are less than or equal to the input. int isMaxGeqInput(const T input[k]) const; //check whether al1 the maxs are greater than or equal to the input. int isDataInRange(const T* mi*, const T* ma)const; //check whether al1 the data are inside the given range. int isDataInRange(const T* minR, const T & highl) const; //check whether al1 the data are inside the given range. int isDataInRange(const T & low 1, const T* maxR) const; //check whether al1 the data are inside the given range.

Figure 3.4(b) The description of the member functions of class KDSSkipNode.

For class KDSSkipList, it's data members (see Figure 3.5 (a)):

KDSSkipNode *head; //the head. KDSSkipNode "bottom; //the bottom node. KDSSkipNode *tail; //the tail node.

Figure 3.5 (a) The data member of the class KDSSkipList. public: KDSSkipList(); Ilconstructructor of KDSSkipList. -KDSSkipList() (clear(); ) /ldestructor of KDSSkipList.

const KDSSkipNode* getHead() const (retum head;) int getheightf) const; //returns the height of this k-ci Search Skip List. int insert(const T val[k], char* narne=NULL); Ilinsert the data val[k] and name into the k-d Search Skip List. const KDSSkipNode* search(const T& vai, long& numOfcomps) const; //returns the node whose keys[0][0] matches the input. void rangeSearch(const KDSSkipNode& startNode, const T minRange[k], const T rnaxRange[k], const T T& maxFirst, long& numFound) const; //perform rangesearch on k-d pnority search tree constructed using //a deterministic skip list. void rangeSearchUp(const KDSSkipNode& startNode, const T minRange[k], const T& highl , //max range for x, const T& maxfirst, lonf& numfound) const; Ilup semi-infinite //perform up semi-infinite range search on k-d priority dearch tree Ilconstructed using a deterministic skip list. int deleteNode(const T& v); //delete a node rnatching the input key. void printList() const; Ilprint the whole skip list.

pnvate: void newMaxMin(KDSSkipNode& inNode); // reset the mm and min for x3, ..., xk for inNode. void printNodeData(const KDSSkipNode& node) const; Ilprint the node (without the minimum and maximum). void printNodeMin(const KDSSkipNode& node) const; Ilprint the node's minimum values. void printNodeMax(const KDSSkipNode& node) const; //print the node's maximum values. void clear(); //clear the whole list.

Figure 3.5 (b) The rnember functions of the class KDSSkipList. - A

Constmcting a k-d Search Skip List requires inserting each point into the k-d Search

Skip List sequentially, starting with an empty k-d Search Skip List. Algorithm 3.1 can be used for this. As the k-d Search Skip List is constmcted by inserting one point at a time, we

discuss the time and space requirements for building the structure in the section on insertion.

Note that minkey and maxkey are special constants which delineate the range that al1 data

points must fa11 in.

3.4 Insertion in a k-d Search Skip List

Insertion proceeds sirnilady to that of the 1-3 DSL and the 2-d Search Skip List

Nickerson [1994] with the only difference being that we must check the minkey and rnaxkey

for each dimension except for dimension 1. Note that the algorithm relies on the private data

members head, tail and bottom of the instantiation of the KDSSkipList (I, class along with

the concepts of lefi subtrees and gap size. In addition, we assume that al1 of the K

coordinates are unique and that the data point is not already in the k-d Search Skip List.

The (top down) insertion algorithm, in summary, is as follows: A. uraL aL nic iicilu iiuut: UL LnG 3CWCïl SKlP LISI.

2. If the gap we are going to drop into is between Lm/2 J and m- 1, determine where to drop,

and alter the minkey or rnaxkey of the dropping node as appropriate.

3. If the gap is of size m, we first raise the middle element of the gap by allocating a new

node C to create two gaps of size Lm/2J and m - Lm/2J. We then drop as appropriate

and alter the minkeys and maxkeys of the dropping node and the node C as

necessary. If raising an elernent implies the existence of two elements at depth O, we

must raise the height of the skip list by creating a new header node.

4. When we reach the bottom level, we insert a new element of height 1. This new element has a minimum and maximum value of Ki, where i = 2,3, ..., k.

Algorithm 3.1 Summary of insertion steps in a k-d Search Skip List.

Algorithm 3.2 can be used for insertion of a point fkom a k-d skip list. Algorithm 3.2

corresponds to the C++ pseudocode used for insertion. void KDSSkipList::insert(const T val [k], char* name) { int addl = O; success = I ; bottom->keys[O], keys[ 11, keys[2] = val; bottom->name = name; tmpNode = head; while (tmpNode != bottorn) //at each level

find the node in the right direction such that val < key, renarne the node as tmpNode; if (tmpNode->keys[O] [O] > trnpNode->down->right->right->keys[O][O]) { insert a newNode betwee tmpNode and tmpNode->right; newNode->down = tmpNode->down->right->right; //middle one newNode->keys[O] = tmpNode->keys[O]; newNode->name = tmpNode->name; adjust the min's and max's for newNode (considering val) tmpNode->keys[O] = tmpNode->down->right->keys[O]; tmpNode->name = tmpNode->down->right,>name; adjust the min's and max's for newNode (considering val) addl = 1; 1 else if (tmpNode->down = bottom) //insert key already in the list success = 0; if ( tmpNode->down != bottom && !addl) t min of tmpNode = min (min of tmpNode, val); max of tmpNode = rnax (max of tmpNode, val); 1 trnpNode = tmpNode->down; 1 if (head->right != tail) raise height; (i.e. create a new head) return (success);

Algorithm 3.2 Insertion of data val[k] and narne into a k-d Search Skip List. down to the leaf level and the resulting skip list with a newly inserted element is a valid

order m skip list (i.e. has gap sizes between Lm121 and m). Since the minimum and

maximum value of &, where i = 2, 3, ..., k are always determined with respect to the new

point's Ki coordinate value, the minimum and maximum value of Ki, where i = 2, 3, ..., k

for a node are always correct.

The following Iernma is used in determination of the storage cost and the worst case

rebuilding cost which are necessary for one to determine the update cost functions and

preprocessing cost.

Define path length as the number of nodes encountered when travershg a k-d Search

Skip List.

Lemma 3.1 The path iength fkom the head node tu the bottom level in a k-d Sestrch

Skip List is O(1og n).

We omit the proof of Lemma 1, since it closely follows the method achieving a

similar result for the 2-d Search Skip List in Nickerson [1994].

Theorem 3.1 The time I(n, k) required to insert a new point into a k-d Search Skip List is

O(k1og n).

Proof

The proof depends on the longest path length encountered on insertion. Insertion

always starts at the head node, and proceeds via a single path to the bottom Ievel, whereupon

the new point is inserted. Along the way, new nodes may be created to increase the height

of middle elements in the skip list. The time to create a new node is considered constant as

33 ir mamy requires me copying or pointers and Checkmg ol: minimum and maxlmum values.

The longest path length encountered on insertion for the k-d Search Skip List is given by Lernrna 1 as O(1og n). The maximum number of new nodes inserted on the way to the bottom level is equal to the maximum height of the k-d Search Skip List, which is (from the proof of Lemma 1) llog nJ + 2 (as a new head node may be required if the height increases by one), in order to get the position where you want to inseri the new node in the k-d Search

Skip List, there are 2k comparisons. This gives the time I(n, k) to insert a new point into a k-d

Search Skip List as O(klog n). QED.

Theorem 3.2 The space S(n, k) required for storage of a k-d search skip list is O(h).

Proof

Each node in the k-d Search Skip List has two pointers and (3k-2) data values. From

Lemma 1, it is known that the number of nodes at each level l is and that the

maximum height of the k-d search skip list is Llog n]. The total number of nodes in the worst

11% nJ case is thus (Il;]+Cvaluatinp this surn results in O(logn) + O(%) Assutning that

each pointer and data value occupy one storage space, the worst case storage requirement for

a k-d search skip list is 3k(O(log 11) + O(2n))= O(kn). QED.

Theorem 3.3 Using Algorithm 3.2, the time P(n, k) required to constmct a k-d Search

Skip List is O(kn log n). IlUU1

Each point to be inserted into the k-d Search Skip List is first checked to see if its

K, value is already there. This requires O(log n) time as, in the worst case, the longest path

(Lemma 1) will have to be followed to determine if the point is already there. If the K, value is not already there, the point is then inserted into the k-d search skip list. From

Theorern 3.1, we know that this requires O(k1og n) time. These operations are canied out a total of n times, once for each point inserted into the k-d search skip list, resulting in a total time of n(O(k1og n) + O(1og n)) = O(kn log n). QED.

3.5 Range Search for a k-d Search Skip List

Algorithm 3.3 cm be used to perform a k-d orthogonal range search on a k-d Search

Skip List. Note that it is in some ways more involved than the search algorithm for the range

tree as we do not always know at which node in the irnrnediate down subtree we are to

continue our search and must allow for this situation. This procedure may also be used for

a member query which is the special case where our search interval is a data point.

The algorithrn assumes that the Search Skip List data structure we are currently

searching is built in a top down fashion and that the query ranges are given in the variables

minRange and maxRange.

Algorithm 3.3 can be used for orthogonal range search on a k-d Search Skip List.

Again, Algorithm 3.3 corresponds exactly to the C++ code used for range search in the

experiments. " // deterministic skip list. i.e. report al1 points lying inside the range / / ( [minl:maxi] , [min2: max21 , . . . , [mink: maxkl ) .

template void KDSSkipList::rangeSearch(const KDSSkipNode& startNode, const T minRange[k], const T maxRange[k], const T& maxFirst, long& nurnFound) const { if ((&startNode != bottom) && (&startNode != tail))

if ((startNode.down != bottorn) && (startNode.isMinLeqInput(maxRange)) && (startNode.isMaxGeqInput(minRange))) { // Not leaf level // Check the first data to see which branch it goes if (*minRange <= startNode.keys[O][O]) rangeSearch(*startNode.down, minRange, mafiange, startNode.keys[O][O], numFound); if ((startNode.keys[O ][O] < *rnaxRange) && (startNode.keys[O][O] < maxFirst)) rangeSearch(*startNode.right, minRange, maxRange, maxFirst, numFound); t else if (startNode.down == bottom) { // leaf level, report points if in range if (startNode.isDataInRange(minRange, maxRange))

//printNodeData(startNode); numFound++;

// Keep check the right points if ( (starNode.keys[O] [O] < *maxRange) && (startNode.keys[01[0] < rndirst) ) rangeSearch(*startNode.right, minRange, maxRange, maxFirst, numFound); > }

Algorithm 3.3 Range search algorithm for a k-d Search Skip List ------v --. " I ------less than or equal to the maxRange (which is the upper right of the searching region); the method ".isMaxGeqhput(minRange)"checks whether al1 the maxs are geater than or equal to the minRange (which is the lower lefi coordinate of the searching region); and the method

".isDataInRange(rninRange, maKRange) checks whether al1 the data are inside the given range.

Theorem 3.4 The time Q(n k) list required for range search in a k-d Search Skip List is

Wn).

Proof

The worst case for k-d range search with a k-d Search Skip List is illustrated in

Figure 3.4. In this case, there are no points in the range, but the rangesexch algorithrn must

search n nodes to make this determination. The points are organized in the K, keys such that

they alternate between the minimum and maximum K ,... ,K, key values. This means that

the lefi subtrees of al1 nodes in the upper levels have the same minimum and maximum K,

, ... ,Kk key values. Thus, the test at line 6 of the rangesearch algorithrn never prunes any

subtrees as the minimum K , ... ,K, values are always less than maxRange (i.e. the upper

bound of the query), and the maximum K, ,... , K, values are always greater than minRange

(Le. the Iower bound of the query), until the bottom level is reached. This means that O(kn)

nodes are checked to determine that no points are in the desired range. QED- Figure 3.6 Illustration of worst case for 2-d range search with a 2-6 search skip list.

3.6 Semi-infinite Range Search in a k-d Search Skip List

Interestingly, the k-d search skip list cm be used for semi-infinite range search, in either the (CL,: H ,1, [Lz: 001, [L3:001, .. . [Lk,ml), or the (CL,: H,1, [-=: HJ,. . . , [-=: HJ)mode.

We cal1 these the "Up" mode and "Down" mode, respectively. Algorithm 3.4 can be used for the Up semi-infinite range search; the Down semi-infinite range search algorithm is in the source code. The primary difference between this algorithm and the general k-d range

search in Algorithm 3.3 is at line 6, where the subtree pruning only occurs if the maximum

& , ..., K, values are less than the lower bound on the semi-infinite query for the keys (Le.

al1 K2 , ..., Kkkeys are now out of range). //constructed using a deterministic skip list . i. e., report al1 points / /lying inside the range { [minl: maxll , [min2: inf inity) , //. .., [mink:infinity)).

template~classT> void KDSSkipList::rangeSearchUp(const KDSSkipNodecT>& startNode, const T minRange[k], const T& high 1, const T& maxFirst, long& nuMound) const

if ((&startNode != bottom) && (&startNode != tail)) { if ((startNode.down != bottom) && (startNode.isMaxGeqInput(minRange))) ( Il Not leaf level // Check the first data to see which branch it goes if (*minRange <= startNode.keys[O] [O]) rangeSearchUp(*startNode.down, minRange, high 1, startNode.keys[O] [O], nudound); if ((startNode.keys[O] [O] < high 1) && (startNode.keys[O] [O] < mafiirst)) rangeSearchUp(*startNode.right, minRange, highl ,mdirst, numFound); 1 else if (startNode-dom == bottom) ( Il leaf level, report points if in range if (startNode. isDataInRange(minRange, high 1)) ( //printNodeData(startNode); numFound++; 1 // Keep check the right points if ( (startNode.keys[O][O] < highl) && (startNode.keys[O][O] < maxFirst) ) rangeSearchUp(*startNode.right, minRange, high 1, maxFirst, numFound); 1 1

Algorithm 3.4 Up semi-infinite range search for a k-d Search Skip List. '1he aigonthm 3.4 can be stated in the pseudo-code form as the follow:

1. Start at head node.

2. Ifnot bottom and tail node, then check

If not leaflevel and L2Li,i = 2, ..., k,

If L, I, K, search down;

If K, < Hl and K, < M, search right;

If leaf level, check

IfLi 5 Y s Y, i= 1, ..., k, report;

If K, < H, and K, < M, search nght;

Algorithm 3.5 Up serni-infinite range search pseudo-code form for a k-d Search Skip List.

Theorem 3.5 The time Q(n, k) required for semi-infinite range search in a k-d Search

Skip List is O(& + kn), for t = number of points found in the range.

Proof

We consider the following cases (Figure 3.7 and Figure 3.8).

In Figure 3.7, there are no points in the range, the test at line 6 of the rangeSearchUp

algorithm will prune al1 the left subtrees as the maximum K, , .. ., K, values are less than the lower bound on the serni-infinite. This means that O(1) nodes are checked to determine that no points are in the desired range. This is not the worst case semi-infinite range search. Figure 3.7 Illustration of no data point in the 2-d up semi-infinite search region.

The worst case for k-d semi-infinite range search with a k-d Search Skip List of order m is illustrated in Figure 3.8. There are some points in range, but the rangeSearchUp algorithm must search n nodes to make this determination. The points are organized in the K, keys such that alternately, there is one point less than the minimum K, , . .., K, values and one point great than the minimum K, , .. . , K, vdues. Thus, the test at line 6 of the rangeSearchUp algorithm never prunes any siibtrees as the maximum K,, .. ., K, values are always greater than minRange (Le. the lower bound of the query), until the bottom level is reached. This means that al1 nodes in the k-d Search Skip List are visited to determine that t points are in range. Thus the time requirement for this worst case is O(kn + kt). QED.

Figure 3.8 Illustration of worst case for 2-d up semi-infinite range search with 2-d

Search Skip List of order 3. Deletion for a k-d search skip list requires keeping track of the path followed to the

bottom on the deletion path, and then reestablishing the minimum and maximum K, values

in a bottom up fashion after the node is deleted. There is a complication if the gap is of

sue Lm/2J. Bomwing fiom the next (or previous) gap causes a node to have a different lefi

subtree. This, in tum, means that the mink2, ..., minkk and maxk2, ...,

maxkk value for this changed node must be reevaluated before proceeding to the next \ level. A summaty of the deletion steps is given below in Algorithm 3.5. 1. Start search at the header, at a level = height of skip list. 2. The current node has a gap G of size Lm/2], .. ., m-1 or m; record the current node in an array P. 3. If gap G we are going to drop into is of size Ld2J + 1, .. ., m-1 or m, drop. 4. If the gap G is of size Lm/2J, then: 5. If G is not the last gap in the current level, then 6. If the following gap G' is of size Lm/2], merge G and Gy(by lowering the eiement separating G and G'). 7. Else if Gyis of s'i Lm/q +1, .. ., m-1 or m, we borrow Rom it (by lowering the element separating G and G', and raisiig the first element in G'). The minimum and maximum K, values of the top node of the first element in G' are reset to correspond to its new left subtree nodes. Else if G is the last gap, then If the preceding gap G is of size Ltn/2J, merge G and G' @y lowering the element separating G and G'). Else if Gyis of size Lm12 J + 1, .. . , m - 1 or m, we borrow from it (by fowering the element separating G and G', and raising the last element in G'). The minimum and maximum K, , ..., K,values of the top node ofthe last elernent in G' are reset to correspond to its new left subtree nodes. 1 1. Continue until we reach the bottom level, where we remove the element of height 1 (if the key to be deleted does not have height 1, swap with its predecessor of height 1 and remove its predecessor). 12. Follow the pointers in array P from the bottom up, reestablishing the minimum and maximum K, , ..., K, values for al1 nodes on the deletion path.

Aigorithm 3.5 Summary of deletion steps in a k-d search skip list Algorithm 3.6 can be used for deletion of a point from a k-d Search Skip List.

Again, Algorithm 3.6 corresponds the C++ pseudocode used for deletion in several //delete a node matching the input key.

1 template 2 void KDSSkipList::deleteNode(const T& v)

push head to a stack bottom->kkeys[O][O] = v; x = head->down; while (x != bottorn) //for every level { go to the right to find the first x such that x->keys[0][0] > v; let IastAbove = key of 1astAbove node of x; if x has gap size Lrn/2], then { if (x->keys[O][O] != lastAbove) //x is not the last gap ( t = x->right; if ((t has gap size Lm12) or (x is leaf level)) merge x and t->right by delete t; else //bas gap size great than Lm/2J ( x->keys[O] = t->down->keys[O]; t->down = t->down->right; reset min's anci max's for t; } 1 else if previous gap of x has gap size Lm/2]; ( merge px and x->right by deleting x; renarne px as x; } else //PX has gap size great than Lm/2J ( px->kkeys[O] = keys[O] of the last second node of the gap px; x->down = t->right; reset min's and mm's for px; } 1 push x stack, x = x->down; 1 do a second pass fiom head->down, remove the element of height 1. If deleted key in element of height > 1. Swap with its predecessor of height 1 and remove its predecessor; reset min's and mm's for al1 nodes in the stack; lower the head if necessary; return (success);

Algorithm 3.6 Deletion of a node from a k-d Search Skip List. is O(k1og n).

Proof

As for insertion, the proof depends on the longest path length encountered on deletion.

Deletion always starts at the head node, and proceeds via a single path to the bottom level, whereupon the existing point is deleted. Along the way, gap heights are possibly changed by borrowing fi-orn a next or preceding gap, and then resetting minimum and maximum K

, .. ., K, values. The borrowing requires the changing of one pointer. Resetting minimum and maximum K2 , ..., K palues is done by a cal1 to the function getmin, getmax, which compares the values of up to two other nodes, and resets if appropriate. The time for these operations is considered a constant.

The iongest path length encountered on deletion for the k-d search skip list is given in

Lemma 1 as O(1og n). Following this path to the bottom, and deleting the node thus requires

O(1og n) time. In addition, the deletion path is followed again to check for deleted K, keys in nodes higher than the bottom. This also requires O(1og n) time. Finally, the deletion path is followed fiom the bottom up to reestablish the correct minimum and maximum K2 , ...,

Kkvalues, which requires O(k1og n) time. The total time required is thus 20(log n) + k

O(1og n)= O(k1og n) time. QED. Lliapier 4 LOWER BOUNDS

In order to formulate a lower bound, we have to define an appropriate model of computation, the so-called tree model. In this model, a data structure is a rooted tree, and a condition is associated with each edge in the tree. Given a query, the query answering algorithm starts with the root, and visits a vertex v if and oniy if the given query satisfies the conjunction of the conditions on the path fiom the root to v. The output corresponding to a given query is a fùnction of the data associated with the visited vertices. Several standard

data structures, such as linked lists, and range trees are based on the tree model. In the tree

model, we investigate the semi-infinite reporting problem where the response to a query is

a Iist of al1 the records in the data base whose keys are located in the query box.

The Iower bound for the worst case time to process (on-line) a sequence of n

intermixed insertions, deletions, and range queries is P(n(1og n)k)Fredrnan [198 11.

It is convenient to transfonn the problem of semi-infinite range searching in a k-

dimensional set F of n points with arbitrary real coordinates into the problem of range

searching in a k-dimensional set Ft of n points with integer coordinates between 1 and n.

Such "normalization" cm be canied out as follows. Let Fi = (xi 1 x E F) (1 5 i k)

be the set of n numbers occuring as the i-th coordinate. For each point x = (x,, x2, ..., x,) of

F take a point x' = (x,', xzt, ..., x,') into FI, where xi' is the "rank" of xi in Fi. (If the

numbers of Fi are sorted into ascending order and duplicates are removed, then the position

of xi in this sequence is its rank). Note that such normalization can be accomplished in time

47 VtRIIIVg CUAU 3pQbG ~\11). fi li~llg~yutxy q J, 11~, -1, .. ., kL , 031 in k can be

"norrnalized" into a range query [LI', H, '1, [L, ', a], .. ., [L',=] in F' in a sirnilar fashion in

(k + 1) log n comparisons.

For the above reasons, we can assume in the following that F is a set of n points in k dimensions with al1 coordinates being integers between 1 and n, and that each range query

[LI, H,],[L, ml, ..., F, =] consists of integers only with 1s Li s n , 1 s H, 3 n, for i = 1, 2, ..., k.

4.1 No Space Restriction

For an arbitrary point set F, let R(F) be the number of difTerent serni-innnite range queries possible for F (we assume that two range queries are Mirent iff the results of a range search based on them are different).

Let R(n, k) = max(R(F)IF is a set of n points in k dimensions).

It is easy to see that R(n, 1) = + 1 = (n+l)n/2 + 1, for the answer to a range query is

either empty (one such answer) or cm be defmed by two of n+l interpoint locations. It is also

easy to see that R(n, 2) = R(n, 3) = ... = n +l.

The exact value of R(n, k) for general n and k seems more difficult to cdculate. We

can immediately observe that R(n, k) s [(n+l)n/2 + l][n + 1]*?

Lemma 4.1 R(n, k) 2 (n/(2k))@+*'".

Proof

To avoid complications assume n is a multiple of 2k. Let S be the set of al1 points ------a--- VLVouu ulLwi v L-tu [LAI, IU ~LICJJ. .d umsiut;r me set of al1 range queries [LI,HI], EL2, ml, ..., [Lk7m] with -n/(2k)

Theorem 4.1 For range queries on n points in k dimensions, the lower bound for semi- infinite range search time is Q(klog n).

Proof

By the Lernma 4.1, R(n, k) z (n/(2k))(k+1).Hence any algorithm for semi-infinite range search based on decision trees in the worst case requires at least

Ig (nl(2k))("l) = (fil) log n - (k+ 1)log k - (k+ 1)log 2 comparisons. Hence the lower bound for semi-infinite query time is O(k1og n). QED.

4.2 With Space Restriction

Space and time requirements have traditionaily been used as performance measures for the algorithm of range search. We investigate the question of (storage) space-(retrieval) time trade-off for semi-infinite range queries on a static data base.

Let k be a positive integer. Let N = (1,2, ..., nj and let Nkdenote the set of al1 k-tuples of positive integers less than or equal to n. Let (K,, K,, ... ,K,) E F. A semi-infinite range query is specified by a (k + 1) - tuple (L,, Hl, L2 , 00, L3, 00, ..., Lk, =) of positive

integers satisfying LI < HI. Altemately, the query region for a semi-infinite range search is a parallelepiped (box) b, defined by the product [L , H ] x [ L of k intervals. A key k is said to be located in a box b = [L,, H,] x [ L, , a) x [ L3, -) x .. .

x [k00) (b = [LI, Hl] x [ L2, maxK,) x [ 5,maxK,) x .. . x [b,maxKk)) if and only if

L, a K, 5 Hl, Li I Ki r m, 2 5 i 5 k. We consider such a query where the output is a list of al1 the records whose keys lie in the query parallelepiped b.

We study the tree model for data structures. In this model, the data structure is assumed to be a rooted tree.

We shall only consider sets of records where no two records in a set have the same key. Then the set F of keys completely specifies the set of records, and the semi-infinite reporting problem is to produce a list of aU the keys in F that lie in the given query box. Note that considering this special case does not cause any loss of generality as the lower bounds obtained in the special case tnvially extend to the general case. Since the output size is query dependent, the time required to answer a query is not the correct measure of the overhead involved in producing the desired respowe to the query. So we define a scaled query time T' that measures the overhead for producing one unit of output. With respect to a fixed set F of keys, and a fixed tree for F, we define a scaled query time T' as follows:

Theorem 4.2 In the tree model, for the semi-infinite reporting problem on a static data base with n records, there is a space-time trade-off (where S = space, T = time) /, VVLLYL~ w - I 1u1 n - L, . Y u O -1 - - ..,

and 8 = 2 for k 2 3.

Proof

From Vaidya [1989], the orthogonal reporting problem on a static data base with n records, the space-time trade-off is (log T' + log log n) ' lT'S = O(n(log n) "7, where 0 =

1 for k = 2, and 8 = 2 for k 2 3. Again, the lower bound of T'S for Up semi-infinite range

search is the same as that for Down semi-infinite range search; the lower bound off's of the

Up semi-infinite range search, the Down semi-infinite range search, and the intersection

between the Up semi-infinite range search and Down semi-infinite range search would be

that for the orthogonal range search; and the lower bound of T'S of Down semi-infinite

range search is the same as that in the orthogonal case. Therefore, the space-time trade-off

for the semi-infinite report hgproblem is (log T + log log n) - 'T'S = O(n(1og n)k-O), where

8 = 1 for k = 2, and 0 = 2 for k r 3. QED.

This type of lower-bound argument, when used to prove a worst-case result, is

sometimes known as an information-theoretic lower bound. The general theorem says that

if there are P different possible cases to distinguish, and the questions are of the form

YES/NO, then r log Pl questions are always required in some case by any algorithm to solve

the problem Weiss [ 19921.

The most obvious open problem 1eR by this work is that of further tightening the

bounds. We suspect that the above lower bound for semi-infinite range search without space

restriction (Theorem 4.1) is exact up to second-order terrns. Chapter 5 HALF-SPACE RANGE SEARCH

When we discuss half-space range search, if we don't specifically mention it, we search the points locate in the positive side of a hyper plane h. The hyper plane h has the equation: alxl+ a2x2+ ... + %xk = m, where we always assume a, * 0.

To perform a half-space range search, we modie the composition of a single node in a k-d Search Skip List as follows:

1 datapoint 1 min. K,value in the ma..K, value in the l lefi subtree 1 lefi subtree min. & value in the max. K, value in the I left subtree 1 left subtree 1

min. K, value in the max. K, value in the left subtree 1 left subtree 1 l -- down pointer right pointer i I

Figure 5.1 Modified composition of a single node in a k-d Search Skip List to allow half-space range search.

The difference between the composition of a single node in a k-d Search Skip List and the modified one is that we add the minimum and maximum of al1 k coordinate values in the left subtree into the node representation. A sampïe of a modified k-d Search Skip List (see Figure 5.2).

head

Figure 5.2 Sarnple modified k-d Search Skip List.

Note that M stands for the maximum coordinate value and m stands for the minimum coordinate value. The down and right pointers point to the left and right subtrees, respectively. The algorithms for insertion of points into and deletion of points from the modified k-d Search Skip List are not given here as they are similar to the Search Skip List algorithrns. Special nodes head, tail and bottom are used in these algorithms to mark the beginning and end of data. Each leaf node contains one datapoint; these are maintained in order of 1" coordinate values. Interior nodes have a datapoint equal to that of the rightmost leaf level data point in the left subtree of this interior node. 5.1.1 The Half-Space Range Search Algorithm

Let h: ax + by - c = O (a + O) be a hyper plane in E', F be a subset of E2.

For b + O, let y' = (-ax,, + c)/b, y" = (-ax,,. + c)/b (see Figure 5.3). Sirnilarly, let

X' = (-bymin+ c)/a, xl' = (-bymax+ c)/a.

Figure 5.3 Half-space range search for the 2-dimensional Search Skip List.

We assume that there is no point lying on the query line h.

Lemma 5.1 For any point (x, y) E F, we have

(i) if b > O, then y < min(yl, y") implies ax + by -c < 0, and

y > max(yl, y") implies ax + by -c > 0. ----a- \J y J / .."y..VU &&,. UJ Y V, CUlU \--/ -- - -, Ir "-"- . -

y > max(yl, y") implies ax + by -c < 0.

(iii) if a > O, then x < min(xl, xtl)implies ax + by -c < 0, and

x > max(xl, x") implies ax + by -c > 0.

(vi) if a < 0, then x < min(xl, x") implies ax + by -c > 0, and

x > max(x1,x") implies ax + by -c < 0.

Proof

If b + 0, for any point (x, y)€ F, let y, = (-ax + c)/b, y, = min(yl, y"), y, = max(yl, y"). By

Figure 5.3, we have y, s y, 5 y?.

(i) Let b > O. If y < y,, then

y < y, r y. = (-ax + c)/b,

or

by < -ax + c,

that is

ax + by - c < 0.

If y > y,, then

y > y2 z y. = (-a+ c)/b,

or

by > -ax + c,

that is

ax + by - c > 0.

(ii) Let b < O. If y < y,, then d 8 du \-- -/.-y

or

by>-ax+c,

that is

ax+by-c>0.

If y > yî, then

y > y3 2 y0 = (-a~+ c)/b,

or

by<-ax+c,

that is

ax+by-c<0.

(iii), (vi) are SimiIar to case (i), (ii). QED.

From Lemma 5.1, we can get the 2-d half-space range search (top down) algorithm for Our k-d Search Skip List:

1. Start at the head node of the Search Skip List.

2. Calculate x' and x".

If (a > O and x,,. < min(xl, x")) or (a < O and x,,, > max(x', x"))

we prune this left subtree, exit.

Else if (a > O and Xmin > max(xl, x")) or (a < O and x,,, < min(x', x"))

we report this lefi subtree, exit.

Else (check b)

If (b +O), calculate y' and y". - - \u v Uri- J max ' AflALA\J' ? Y 11

(b < O and Ymin 'max(yl, y")) we prune this lefi subtree, exit.

Else if (b > O and y,;, > max(yt, y")) or

(b < O and y,,, < min(yl, y"))

we report this lefi subtree, exit.

Else go to Step 3.

Else go to Step 3.

3. Following the down pointer or the right pointer, recursively go to Step 2.

4. When we reach the bottom level, we check whether the remaining points fa11 in

the given half-space.

5.1.2 Analysis of The Half-Space Range Search for The 2-d Search Skip List

Theorem 5.1 Given a set of n points in E2, one cm preprocess it for half-space range

reporting in time O(n log n), storing the data structure in space O( n ).

Theorem 5.2 Given a set of n points in E2, the worst case half-space range search time is O( n ).

We omit the proof of these theorems, since it foltows the proof for the k-d Search

Skip List in Section 5.2. 5.2.1 The Half-Space Range Search Algorithm

In last section, we discussed half-space range search in E'. The purpose of this section is to generalize the results for E2 case to the generai case EL,where k is any positive integer greater than 1.

Although our arguments are developed in EL,for ease of presentation, al1 Figures will represent 2-dimensional analogs. Given a hyper plane h of equation AXT= m, where vector

A = (a,, a*, ..., a,J, X = (x,, x2, ..., xJ, and m is a constant. Given a set of points F in EL,we want to find which points in F are in the positive half-space of h. We assume that no point lies on the query plane h.

We would like to introduce several definitions first.

Definition 5.1 We Say p = (x,, x,, ..., xk)belongs to the positive half-space of h, denoted p E h*,if A (xi,x*, .. ., x~)~- m > O. We define the negative half-space of h, h#, in a similar fashion by reversing the inequality in above.

Detïnition 5.2 For a given set F in Ek,and any integer i, 1 I is k, ximinis defined as the minimum value of the xi coordinates of al1 the points in F. Simitarly, xi,,, is defined as the maximum value of the xi coordinates of al1 the points in F.

Definition 5.3 For a given set F in EL,we define two k-element arrays, mins and maxs:

For any integer i, 1 2 ir k, -a,x,,,, a,< O min s[i]= O, zf ai=O -a, zf a, > O

-a,x,-, rf a, < O maxs[i] = O, if a,= O

-aiXimin t a,>O

Definition 5.4 For a given set F in E~,we define two discrete functions, f,and L, defined on the set (1, 2, ..., k): For any integer i, 1s ir k,

Lemrna 5.2 Let F be a subset of E~.Then for any point p = (x,, x,, .. ., xh E F, we have

mins[i] 5 -a,x, 5 maxs[i], i = 1, 2, ..., k.

Therefore

Since for 1 s i i k, n 5 x, r L, if q < O, we have

That is mins[i] 5 -a,% s rnaxs[i].

Similarly, if a, r O, we have

That is Similarly, if a, r O, we have

'aiXimin 2 -aixi 2 'aiXimax.

That is

maxs[i] r -ai xi r mins[i].

By above and Definition 5.4, it is not difficult to get

fi()f, (i),i=1,2., k. QED.

We assume that there is no point lying on the query plane h.

Lemma 53 Let h: AX~= m be a hyper plane in Ek,F be a subset of Ek and i be an integer between 1 and k. If q + O, let

xfi= (fmins(i)+ ml/%,x''~ = (fmaxs(i)+ m)/q, then for any point p = (x,, x,, ... x,) E F,

(1) if q > O, then xi x x; implies p E h#,

and xi > xWiimplies p E h*,

(2) if a, < O, then xi4 xfliimplies p E h*,

and xi > xtiimplies p E h#,

Proof

Given 1 s i < k, if a, + O, by Lemma 5.2, we have a,~'~s a$',.

For any point p = (x,, x2, ... x,) E F,

let

xiO= (C(-aj *xj)+ rn) la,, (1) Let q > O, if xi < x', then

jti

Hence

Hence

PE h'.

(2) Let ai < O, if xi

p E h*.

Hence

p E hu. QED.

From Lemma 5.3, we can get the k-d half-space range search (top down) algorithm for our k-d Search Skip List:

1. Start at the head node of the Search Skip List.

2. Calculate two arrays: mins and maxs.

Let

h min s = rn + min s[i], i= l For each q + O, where i E (1,2, ..., kt, Calculate xtiand xni:

xti= (hmins + mins[i])/ai, xtf = (hrnaxs + maxs[i])/a,.

If (a, > O and ximax< xli) or (q < O and x > x'~)

we prune this left subtree, break the loop.

Else if (3 > O and ximin> xtqi)or (q < O and ximax< x1Ii)

we report this left subtree, break the loop.

Else

If it is the last loop ak case,

go to Step 3.

Else increase i to discuss next ai case.

3. Following the down pointer or the right pointer, recursively go to Step 2

4. When we reach the bottom level, we check whether the remaining points fa11 in

the given half-space. ------.** CI"& //constructed using a detenninistic skip list. i.e. report al1 points // lying inside the positive side of a hyper plane

template void KDSSkipList::halfSpSearch(const KDSSkipNode& startNode, const T halfSp[k+ 11, const T& maxFirst, long& numFound) const { if ((startNode.keys[O] [0] =rnaxkey) && (startNode-down- bottom)) return; else if ((startNode.keys[O][O] = maxkey) && (startNode.down != bottom) && (&startNode != tail)) { HalfSpSearch(*startNode.down, halfSp, startNode.keys[O][O], numFound); 1 else if ((&startNode != bottom) && (&startNode != tail)) { if (startNode.down =bottorn) { if this point in the given side, report it; if (startNode.keys[O] [O] < maxFirst) HalfSpSearch (*startNode.right, halfSp, maxFirst, numFound); 1 else hot leaf level

check to report or prune down; if report report this left subtree; else if (!prune) halfSpSearch(*startNode.down, halfSp, starNode. keys[O] [O], nurnFound); if (startNode.keys[O][O] < maxFirst) halfSpSearch(*startNode.right, halfSp, maxFirst, numFound); 1 1 1

Algorithm 5.1 C++ pseudo-code algorithm for k-d half-space range search Theorem 5.3 Given a set of n points in EL,one can preprocess it for half-space range reporting in tirne O(kn log n), store the data structure in space O( kn ).

We omit the proof of this theorem, since it closely follows the method achieving a similar resuIt for the k-d Search Skip List with orthogonal range search in Chapter 3.

Theorem 5.4 Given a set of n points in EL,the worst case half-space range search tirne is O( kn ).

Proof

The worst case for k-d half-space range search is illustrated in Figure 5.6. In this case, there are no points in range, but the half-space range search algorithm must search n nodes to make this determination. The points are organized in the x,,~,, < xi < Xlmax, and xj '< xj < xj ",where j = 2,3, ..., k. Thus, the algorithm never prune as xj always in the range

(x, xj"), until the bottom level is reached. This means that O(n) nodes are checked to determine that no points are in the desired side, and each node requires O(k) operations.

Therefore, the search time for half-space range search is O(kn).QED. Figure 5.4 Illustration of al1 data points are in the cross-hatched area for 2-d half-space with a k-d Search Skip List. C hapter 6 EXPERIMENTAL RESULTS

6.1 k-d Range Search and Semi-Infinite k-d Range Search

The k-d Search Skip List was experimentally analyzed using the methodical approach described below, in an atternpt to facilitate an accurate comparison of their actual nui times. We are interested in the average insertion tirne, the average deletion time, and the average search time as the worst-case is not only rare for large structures but difficult to specifl. In this section we outline the general approach that is used in the experimental analysis of the k-d Search Skip List in Section 6.2.

The structure was tested on randomly generated data sets which were uniformly distributed throughout a k-dimensional space. The random data was generated by using the built in fûnction lrand480. Silice we instantiate template T as long, lrand480 can only generate the random numbers between O and 2)' - 1. We chose sarnple sizes n of 1,000,

10,000, and 100,000. The range for the random numbers are shifted such that they are between -(z3'- 1)/2 and (23' - 1)/2. The structure was analyzed based on their construction times, the destruction times, and range search times. It is the construction times and destruction times that allow us to approximate the "hidden" constants of our big-oh analysis

of the insertion algorithms that we perfonned in Chapter 3. Our analysis of the update times

is based on these constants as they aIlow us to make a direct comparison of the structures.

The construction time is defined as the time to build a structure by inserting n points --..-a A YVQC~ UWLLVLI LIIllb 13 Cl3 .r ----=-, --- W. UGllIlCU LllC LIlllc LC) dispose of a structure by deleting one data point at a time until we are left with an empty structure. The range search time is simply the time to execute a k-d range search for a given k-d orthogonal range query. The semi-infinite range search time is the time to execute a k-d range search for a given k-d semi-infinite range search query.

The construction and destruction tirnes were recorded by ruming the programs

(kdskiplist.cc and kdtest-cc) 270 times. Each time the application reported the unsuccessful insertions which was caused by inserting a node whose first dimensional key was the same as that of an existing node in the k-d skip list.

The range search tirne is recorded for 6 different query windows that cover O%, IO%,

30%, 50%, 70%, 100% of the search space, respectively. Given a query window area ratio, which is the ratio of the area of the query window to that ofthe data window, we cari get the

side length ratio which is (area ratio)'Ik, then cal1 the fûnction getQuery Win by using this

side length ratio to get the required query window. The position of this query window is

randomly determined. The query windows are restricted such that they are completely

contained within the search space inclusively. Algorithm 6.1 was used to generate the

random query windows. v WU ~GL~UCLY w lqlm ~WIVL~~KLKJ, inr qwMaxKLk1, int wMinR[k], int wMaxR[k], int keys[SAMPLESIZE][k], float qwRatio[k]) II qwRatio[i]: the ratio of the i-th side of the query window and 11 its corresponding side of the whole window.

unsigned i=O, j=O; II loop index int tempMin, tempMax, temp; 11 Get the whole window for (i=O; i temp) tempMin = temp; if (tempMax < temp) tempMax = temp; 1 wMinR[i] = tempMin; wMaxR[i] = tempMax; 1 // Get the portions randomly int wSideLen; II length of side of the whole window int qwSideLen; 11 length of side of the query window for (i=O; i

// Get the length of each side in integer wSideLen = wMaxR[i]-wMiriR[i]; qwSideLen = wSideLen * qwRatio[i]; if (wSideLen != qwSideLen) { qwMinR[i] = (rand() % (wSideLen-qwSideLen)) + wMinR[i]; qwMaxR[i] = qwMinR[i] + qwSideLen; 1 else { qwMinR[i] = wMinR[ij; qwMaxR[i] = wMaxR[i]; 1 1 Algorithm 6.1 Random query window generation. advance if you want the position of every side of the query window to be generated randomly. In Our test, we only give the side iength ratio for the first dimension. We then create our semi-infmite query window (see Figure 6. l), whose first dimension side position is randomly chosen but whose length (e.g. Z in Figure 6.1) corresponds to the calculated side length ratio. Each remaining side has only one endpoint's position (e.g. a and b in Figure

6.1) which is also randordy created. After we get the query window, we then calculate the area ratio and report it.

Figure 6.1 The query window of 2-d semi-infinite range search. different query windows, and destroyed a total of five times. Also, for each structure that is built, each range search is perforrned 270 times in order to bring the search time into the high rnillisecond range so that accurate timings may be obtained. A single range query is

extremely fast, requiring only a few milliseconds for the largest structures we build.

Five test runs were performed on 2, 5, and 10 dimensional data for data sets that

ranged in size fiorn 1,000 to 100,000 data points. A single test nin consisted of 5 passes

over 9 data structures. Each run tests constructing, destroying, and searching a single data

structure.

Times were obtained by using the built-in function dock, accurate to at least 1 of

a second, which keeps track of the arnount of system time used. Al1 of our times are given

in milliseconds except the search times are in microseconds when the query window area

ratio is O or very small (see Table 2). Due to the size of nklog n as cornpared to the actual

mn tirnes, the constant for building the data structures are calculated (see Table 1) according

to the following equation:

average- run- time * 100,000 - average- nu?- tim f'= w - hilli second nk log n nk log;iQO,OO 1 duit; 1 1 ne value or (nKiog n)i 1 UU,UW for different tests.

1 k Number of data points in the randomly generated datasets

Approxirnating the constant for the range search cost hnction, which is cklog n + t, is difficult. The range search fünction is highly dependent on the time needed to report the t data points in range which is difficult to separate fiom the time required to search the skip list.

The method we use for analyzing the search times is to detennine whether or not the search times increase appropriately with an increase in the size of the query window. For exarnple, when the query window increases fiom 10% to 30% coverage, the search time should approximately triple if the search is performed on the sarne structure under the assumption that t dominates the search time (which Our results seem to indicate).

Our methodology is to average the construction, and search times for each structure built (where one structure corresponds to one data file) and determine Our constants and approximate run times fiom these averages. The results are summarized in the section that

follows. Appendix B, D, and E contain the complete testing details.

The testing was performed on sol, a Sun SPARC 1000 workstation, under SUN OS

5.3. Sol has 640 MB of RAM and 820 MB of hard disk space available for use as virtual

memory. Sol is located in the computing Services Department of the University of New - - - - .------.A a urhu ub JW AVAA~~.UV6 10 llbQV&ly 1 -, -. used throughout the campus and testing took place on May 20, 1997, when usage was usually below normal.

The C++ pseudo-code for the test runs is shown in Algonthm 6.2. It contains the pseudo-code for the main driver used in testing the k-d Search Skip List along with pseudo- code for the driver functions to accomplish the constniction, orthogonal range searching, semi-infinite range search and destruction of the data structures. The complete source code for the k-d Search Skip List can be found in the appendix H. ---.-- #inchde #inchde #include #inchde #include // library routines #include "kdskiplist-h"

#define SAMPLESIZE 100080L #define QWAREARATlO 0.8 #define MILLISEC-PER-SEC 1 O00 main()

long startT, endT; long i, keysA[SAMPLESIZEl[k]; int j; long* datalter = NULL; il pointer iterator of the array keysA const long maxTest = 5368709 12L;

for (i=OL; ixSAMPLESIZE; i*) { for (j=O; j

KDSSkipList kdlist; // Create an empty skiplist

BUILD the structure and output the construction time; ORTHOGONAL RANGE SEARCH the structure for the given query windows and report the data points in range and the search time; SEMI-INFINITE RANGE SEARCH the structure for the one given side of query windows and report the data points in range and the search time; DESTROY the structure and output the destruction time; 1

Algorithm 6.2 (a) Main driver routine for testing the k-d Search Skip List. long unsucNum = OL; long numFailDe1 = OL; startT = clock(); startT = clock(); startT = clock()/MILLISEC-PER-SEC; startT = clock()/MILLISEC-PER-SEC ; dataIter = keysA[O]; dataIter = &keysA[O][O]; for (i = OL; i < SAMPLESIZE; i++) for (i=OL; icSAMPLESIZE; i++)

if (O == kdlist.insert(data1ter)) if (kdlist.deleteNode(*datalter) - 0) UnsucNurn++; NurnFailDelU ; DataIter += k; DataIter += k; 1 1 endT = clock(); endT = dock(); endT = clock()/MILLISEC-PER-SEC; endT = clock()/MILLISEC-PER-SEC; output unsucNum and endT-startT; output nurnFailDe1 and endT-startT;

Sub-driver ORTHOGONAL RANGE Sub-driver SEMI-INFINITE RANGE SEARCH SEARCH

long qwMinR[k], qwMaxRCk]; numFound = OL; long wMinR[k], wMaxR[k]; calculate the query window area ratio float quRatio[k]; startT = clock(); long nurnfound = OL; startT = clock()MILLISEC-PER-SEC; cal1 getQueryWin(.. .); search the data structure for calculated startT = clock(); semi-infinite qwery window; startT = clock()/MILLISEC PER-SEC; endT = clock(); search the data structure foryhe endT = clock()/MILLISEC-PER-SEC; given query window; output numFound and endT-startT; endT = clock(); output numFound and endT-startT;

Algorithm 6.2 (b) Sub-driver routines for testing the k-d Search Skip List. In this section we experirnentally analyze the k-d Search Skip List of chapter 3. The construction and destruction times for al1 five passes of al1 six msfor randomly generated datasets cm be found in Appendix A. Their average constniction and destruction time can be found in Appendix B. Table 2 and Table 3 below sumrnarize the construction and destruction times for the test runs.

The constants, as computed by equation (6. l), corresponding to the construction and destruction times of Appendix A cm be found in Appendix C and the constants corresponding to the average construction and destruction times of Appendix B can be found

in Appendix D and are summarized in Tables 4 and 5.

Table 2 Constmct time averages for al1 test runs the k-d Search Skip List

1 Construct time average (milliseconds) 1 1 ame s Destruct time averages for al1 test runs of the k-d Search Skip List

k Destruct time average (milliseconds)

n = 1,000 n = 100,000 I n = 10,000 2 57 774 13669 5 84 1373 20807 10 137 2324 32774

Table 4 Average insertion constants for al1 test wsof the k-d Search Skip List

I k Constant c for insertion averages I

Table 5 Average deletion constants for al1 test runs of the k-d Search Skip List

k Constant c for deletion averages

n = 1,000 n = 10,000 n = 100,000 2 9.29 12.86 23.48

5 5.80 9.14 14.01 10 4.55 7.25 1 1 .O9

From Tables 4 and 5, it would appear that the constant for the insertion procedure is reasonable at around 8 and that the constant for deletion is moderately high at around 1 1. - , ------"'-"L VI CIIIAV VIA UTUA CW LllbY UULlL require the sarne amount of rebuilding in the worst case, it was expected that the deletion procedure might be slightly slower than the insertion procedure as it involves extra overhead and requires backtracking along the deletion path when a maximal or minimal value in a down subtree is removed. As with the k-d Search Skip List, we expect the constants to be slightly higher as larger structures reqiiire more overhead which could considerably slow down the construction times, especially when the constant paging and swapping of the process that is bound to happen in a multi-user system is taken into account.

We now turn to analyze the search times (orthogonal range search and semi-infinite

range search). The average orthogonal range search times for the tests are given in Table 6.

Table 6 shows the average range search time when the dimension is 2,5, or IO. It appears

as the area ratios increase, the increment ratios of range search times increase almost the

same as that of the area ratios. We can conclude that the range search procedure is very

efficient on average, behaving as predicted in Our analysis. The average orthogonal range search time (milliseconds) for the k-d Search Skip List

% of points in range 0% 10% 30% 50% 80% 100% Average search time in milliseconds 1

The classified serni-infinite range search times for the tests are given in Table 7.

Table 7 (Appendix E), below, provides the average semi-infinite range search times obtained from Our tests by classieing the percentage of points in range as 10% or less, 40 to 60%, and 90% or more. Examining the average search times of Table 7 leads us to conclude that the semi-infinite range search procedure is very efficient, behaving as predicted in our analysis (Le. O(k1og n + t) tirne on average). The average semi-infinite range search time (rnilliseconds) for the k-d Search Skip List

% of points in range 10% or less 40 to 60% 90% or more k # points Average search time in milliseconds 1o3 O O 4

2 1o4 4 16 38 1o5 38 172 500 1o3 1 4 10 45 5 1o4 20 60 1Os 1O0 500 762 1o3 4 10 10 90 10 1o4 38 70 1Os 180 800 960 I

From the above tables, we can see that the range search ( and semi-infinite range search) times increase as the dimension and query window area ratio increase. With the

increments in query window size from 10-30%, 30-50%, 50-80%, and 80-100%, the

increments of search tirnes should be roughly 3.0, 1.6, 1.6, and 1.2 if t dominates the search

time as predicted. Unfortunately, we didn't get such results because it is impossible to

predict the time for reporting t. For given dimensionality k and query window area ratio, the

results show that the semi-infinite range search time is lower than the range search time,

behaving as predicted in Our analysis.

For the orthogonal range search (semi-infinite range search) tirne, when the query

window is very small, the search time is too little to report, even if microseconds are used as [ne rime unir.

6.3 k-d Half-Space Range Search

In this section we outline the general approach that is used in the experimental analysis of the average half-space range search times based on the modified k-d Search Skip

List.

The structure was tested on randomly generated data sets which was unifonnly distributed throughout a k-dimensional space. The random data was generated by using the built in function lrand48(). Since we instantiate template T as long, lrand480 can only generate the random number s between O and z3' - 1. We chose sarnple sizes of 10,000,

50,000, and 100,000. The range for the random numbers are shifted such that they are between -(Z3' - 1)/2 and ( 23'- 1)/2. The structure was analyzed based on their range search times.

The half-space range search time is recorded for 100 different randomly generated hyper planes (using srand48first.&-sec) to get the seed of the random function Zrund480),

values of k = 5, 7 and 10, and values of n = 10,000, 50,000, and 100,000. We run the

programs (hskd1ist.c~ and kdtest.cc) 900 times. Each time the application reported the

number of data points found in the positive side of the hyper plane.

The C++ pseudo-code for the test runs can be found in Algorithm 6.3. It contains

pseudo-code for the main driver used in testing the modified k-d Search Skip List along with

pseudo-code for the driver functions to accomplish the half-space range searching of the data Appendix H.

#inchde #inchde #include #inchde #inchde dimits.h> #inchde 11 library routines #include "hskd1ist.h"

#define SAMPLESIZE 1OOOOOL #define QWAREARATIO 0.8 #define MILLISEC-PER-SEC 1O00

main() { long startT, endT; long i, key sA[SAMPLESIZE][k]; int j; long* dataIter = NULL; Il pointer iterator of the array keysA const long maxTest = 536870912L;

for (i=OL; i

for (j=O; j

KDSSkipList kdlist; 11 Create an empty skiplist

BUILD the structure and output the construction time; HALF-SPACE RANGE SEARCH the structure for the given hyper plane and report the data points in the given side; DESTROY the structure and output the destruction time; 1

Algorithm 6.3 (a) Main driver routine for testing half-space range search algorithm. long unsucNum = OL; long nurnFailDe1 = OL; startT = clock(); startT = clock(); startT = clock()/MILLISEC-PER-SEC; startT = clock()/MILLISECPER-SEC; dataIter = keysA[O]; dataIter = &keysA[O][O]; for (i = OL; i < SAMPLESIZE; i++) for (i=OL; ieSAMPLESIZE; i++) t if (O = kdlist.insert(datdter)) UnsucNum++; DataIter += k; DataIter += k; f 1 endT = clock(); endT = clock(); endT = clock()/MILLISEC PER SEC; endT = clock()/MILLISEC-PER-SEC; output unsucNurn and end

Sub-driver HALF-SPACE RANGE SEARCH long numfound = OL; get the hyper plane; print the hyper plane; startT = clock(); startT = clock()/MILLlSEC-PER-SEC; search the data structure for the given hyper plane; endT = clock(); endT = clock()/MILLISEC-PER-SEC; output numFound and endT-startT;

Algorithm 6.3 (b) Sub-driver routines for testing half-space range search algorithm.

We now analyze the half-space range search times. The average half-space range search times for the testing done here are given in Table 8. These times correspond to the increases in search time for an increase in dimension k and sarnple size n.

Table 8 (Appendix G), below, provides the average half-space range search times VULSIIIICU lrwn our rem DY ciassnying the percentage of points in range as 10% or less, 40 to 60%, and 90% or more. Exarnining the average search time of Table 8 leads us to conclude that the half-space range search procedure is co~ectand very efficient, behaving as predicted in our analysis.

Table 10 The average half-space range search time (milliseconds) for the k-d Search Skip List

% of points in range 10% or less 40 to 60% 90% or more f k # points Average search time in milliseconds 1 o4 O 5.4 17 5 5*104 0.8 45 90 1 Os 2 110 186 1 o4 O 10 19 7 5*104 1 55 105.4 1 Os 2.6 130 213 1o4 3 9.7 22 10 5*104 4.4 55.6 99.4 1 o5 9 106.6 195.5

Appendix F and G give additional data and results on the testing which was

perfonned on sol. LIIqJLCI 1 CONCLUSIONS

7.1 Summary

We conclude that there is a k-dimensional data structure allowing dynamic updates and range search (orthogonal range search, semi-infinite range search and half-space range search) which maintains a linear storage requirernent and logarithmic preprocessing cost. We label this k-d data structure as the k-d Search Skip List.

We have developed a simple, efficient algorithm and data structure for half-space range search based on the k-d Search Skip List. The dynamic update time of O(klog n) is the fastest we currently know of for a data structure supporting dynamic k-d half-space range search. In addition, this approach has an advantage of conceptual and programtning simplicity compared to other implementations.

The algorithms presented here can search and report data points in a given query window or in a given side of query hyper plane. The analysis of these algonthms in the worst case has been studied. For Our algorithm, the k-d orthogonal range search and k-d half-space range reporting time is O(kn).

The lower bound on time for k-d semi-infinite range search on k-d data points has also been studied, both with and without restriction on the space requirement. This lower bound without space restriction was shown to be Q(k1og n), and ~iiuG 13 a q~u~c-~1111E:LriUC-UII

(log Tt + log log n) = P(n(1og n)"'), where 0 = 1 for k =2, 0 = 2 for k 23, and T' is the scaled query time defined in Chapter 4.

The algorithms and data structures reported here are likeIy to be useful in real applications. Our implementations of these data structures are extremely fast on average for k-d orthogonal range search, serni-infinite range search and half-space range search, even for relatively large k and n. In addition, our algorithms provide very good support for highly dynamic applications due to the guaranteed upper bound of O(k1og n) time on any single insertion or deletion.

Dynamic implementations of the k-d Search Skip List are feasible and have been

implemented and tested here. On average, only 1048 milliseconds was required to report

50% of the points in range for a 10-d orthogonal range search for n = 100,000; about 800

milliseconds was required to report 50% of the points in range for a 10-d semi-infinite range

search for n = 100,000; and 1O6 milliseconds was required to report 50% of the points in

range for a 10-d half-space range search for n = 100,000. The constants in the update

procedures are reasonable, given the linear space requirement.

7.2 Future Work

In this thesis we have made a number of assumptions about Our data set, it's size,

including that of k

happens to Our analysis if points do fa11 on the hyper plane? --=------.- .. UULUIill Unlll L~JLCL~CCAUGIK~~ lm[ on average ror k-d orthogonal range search, semi-infinite range search and half-space range search. What would be the upper bound of the average case search tirne?

There is a trade-off with the worst case range reporting time which now becomes

O(kn). As suggested in Chazelle [1990],this leads one to ask if there is some lower bound

on P(n, k)S(n, k)Q(n, k)U(n, k), for P = preprocessing tirne, S = storage space, Q = time to perforrn range searching for a given hyper plane, and U = time to perform a single update

(insert or delete) operation. In Our case, this product is 0(k4n310g'n)(iporing the time t for

reporting). Other spacekime trade-off studies (e.g. Bronnimann et al [1993]) have been

carried out, and prove that if m units of storage are available, then the worst-case query time

(for k-d half-space range searching) must be on the order of (n~l~gn)~-*~)'~(~-~)Irn'~.What

trade-offs exist if dynamic operations are considered?

Other questions concern that of extending the domain fiom k-d data points to k-d line

segments. How are the range searches (orthogonal range search, semi-infinite range search

and half-space range search) done for line segments? What lower bounds exist for k-d line

segment range searching? Can a structure similar to the k-d Search Skip List be used for line

segments?

In the section on lower bounds (Chapter 4.2), is there an algorithm to tighten the

lower bound of the product of time and space in the tree model? Agarwal, P. K. and Matousek, J., "Dynamic Half-Space Range Reporting and Its Applications". Algorithmica, vol. 13, 1995, pp. 325 - 345. Bentley, J. L., Friedman, J. H., and Maurer, H. A., "Two papers on Range Searching", CMU-CS-78-136(Technical Report of the Departrnents of and Mathematics, Carnegie-Mellon University), August 1978. Bentley, J. L., & Friedman, Jerome H., "Data Structures for Range Searching", Computing Surveys, Vol. 1 1, No. 4, December 1979, pp. 397- 409. Bentley, J. L., "Decomposable Searching Problems", Information Processing Letters, Volume 8, Number 5, June 1979, pp.244 - 25 1. Bentley, J. L., "Mdtidimensional Divide-and-Conquer", Communications of the ACM, Volume 23, Number 4 (April 1980), pp. 2 14 - 229. Bentley, J. L. and Maurer, H. A., " Efficient worst-case data structures for range searching". Acta Informatka, l3(2), 1980, pp. 155- 168. Bentley, J. L., and Saxe, J. B., "Decomposable searching problems I. Static-to-Dynamic Transformations", Journal ofAlgorithrns, Vol. 1, pp. 301 -358 (1 980). Bronnirnann, H., Chazelle, B., and Pach, J., "How Hard IS Half-space Range Search?". Discrete Cornput. Geom. 10, 1993, pp. 143-155. Chazelle, B., "Lower bounds for orthogonal range searching, 1: The reporting case". J. ACM 3 7, 1990% pp. 200-2 12. Chazelle, B. " Lower bounds for orthogonal range searching, II: The arithmetic rnodel". J. ACM 3 7, 1990b, pp. 439-463. Chazelle, B., and Edelsbrunner, H., "Linear Space data Structures for Two Types of Range Search". Discrete. Comput. Geom.2, 1987, pp. 113 - 126. Chazelle, B., Guibas, L., and Lee, D. T., "The power of geometric duality". BIT, 25(1), 1985, pp.76-90. Chazelle, B. and Preparata, F. P., "Halfspace range search: An algorihic application of k - sets". Discrete Comput. Geom. 1, 1986,83-93. Edelsbrunner, H., "A Note on Dynamic Range Searching", Bulletin of the EATCS, Number 15, Oct., 198 1, pp. 34-40. Ewald, G., Larman, D. G., and Rogers, C. A., "The Directions of the Line Segments and of the r-Dimensional Balls on the boundary of a Convex Body in Euclidean Space". Mathernatika, Vol. 17, Part 1. June, 1970, pp. 1-20. Fredman M. L., "A Near Optimal Data Structure for a Type of Range Query Problem". ACM, 1979, pp. 62 - 66. Fredman, M., "A lower bound on the complexity of orthogonal range queries". J. Assoc. Comput. Mach., Vol. 28, No.4, Oct., 198 1, pp.696-705. Fredman, M., "Lower bounds on the complexity of some optimal data structures". SICOMP 10, 1981, pp. 1-10. Guting, H. and Kriegel, H. P., "Multidimensional B-Tree: An Efficient Dynamic file lntonnatik b achberrchte, Springer Verlag, 1980, pp. 375- 388. Haussler, D. and Welzl, E., "mets and sirnplex range queries". Discrete Comput. Geom. 2, 1987, pp. 127-151. Lamoureux, Michael G., "A Dynamic Data Structure for Multi-Dimensional Range Searching", Technical Report, TR96-105, Faculty of Computer Science, Msc. Thesis, University of New Brunswick, 1996. Laszlo, M. J., "Computational Geometry and Computer Graphics in C++",Prentice hall, 1996, pp. 226 - 255. Lueker, George S., " A Data Structure for Orthogonal Range Queries", proceedings of the 19th Annual Symposium on Foundations of Computer Science, Ann Arbor, Michigan, Oct 16 - 18, 1978, pp. 28 - 34. Matousek, J., "Construction of &-Nets9'.Discrete Comput. Geom. 5, 1990, pp. 427 - 448. Matousek, J., "Reporthg points in halfspaces". Comput. Geom. Theor. Appl. 2,3, 1992, pp. 169 - 186. Matousek J., "Geometric range searching". ACM computing Suweys. Vo1.26, No. 4, Dec 1994, pp. 42 1-46 1. McCreight, E. M., "Efficient Algorithms for Enumerating Intersecting Intervals and Rectangles". Tech. Rep. CSL-80-9, Xerox Corp., Pa10 Alto Research Center, June 1980. McCreight, E. M., "Priority Search Trees", SIAM J. Comput., Vol. 14, No. 2, May 1985, pp.257 -276. Munro, J. Ian; Papadakis, Thomas; and Sedgewick, R., "Deterministic Skip Lists", proceedings of the Third Annual Symposium on Discrete Algorithrns, Orlando, Florida, January 27-29, 1992. Nickerson, Bradford G., "Skip List Data Structure for Multidimensional Data", Computer Science Technical Report Series, CS TR-3263 UMIACS CS-TR-94-52, April 1994. O'Rourke, J., "Computational Geometry Column 29". SZGACT News, Vol. 27, No. 3, Sept. 1997, pp. 55- 59. Paterson, M. S., and Yao, F. F., "Optimal Binary Space Partitions for Orthogonal Objects". Journal of algorithms, Vol. 13, 1992, pp. 99 -1 13. Rumbaugh, J., M Blaha, Premerlani, W., Eddy, F. and Lorensen, W., Object-Oriented Modeling and Design, Prentice Hall, New Jersey, 1991 P. 27-3 8. Samet, H., "The Design and Analysis of Spatial Data Structures", Addison-Wesley, Reading, MA, 1990. Saxe, J. B., "On the number of range queries in k-space", Discrete Appl. Math. V. 1-2,1979, pp.2 17-225. Vaidya, M. P., "Space-time tradeoffs for orthogonal range queries (Extended Abstract)". Proc. Of the 17Ih Annual ACM Syrnp. On Theor. Of Comput., 1985, pp. 169 - 174. Vaidya, M. P., "Space-time tradeoffs for orthogonal range queries". SIAMJ. Comput. Vol. 18, No. 4, August 1989, pp. 748 - 758. Van leeuwen, Jan, and Wood, D., "Dynamization of Decomposable Searching Problems", - . . .-----. . - . ------aYYWWY- U, . VIU~ALY 1 V, IF Wiiubi L (IVlCLlblI 1 ;lOW], PY. 3 1-3C). Weiss, M. A., "Data Structures and Algorithm AnaIysis". Second Edition. The BenjarnidCurnrnings Publishing Company, Inc., 1992, pp. 24 1 - 244. Willard, D. E., "New Data Structures for Orthogonal Range Queries", SIAM J. Comput. Vol. 14, No. 1, Feb. 1985, pp. 232 - 253. Willard, D. E., and Lueker, G. S., "Adding Range Restriction Capability to Dynarnic Data Structures", Journal of the ACM, Vol. 32, No. 3, July 1985, pp. 597 - 617. Yao, A. C., "Space-Time tradeoff for answering range Queries", Proc, 14thannual Symp. Theory of Comput., 1980, pp. 128 - 136. Appendix A Raw Construction and Destruction Time for Testing the k-d Search Skip List naw consrruct rime ror pass i of run 1 for tesiing the k-d Search Skip List k 1 Raw construct time (miiliseconds)

Table Al (b) Raw destruct time for pass 1 of run 1 for testing the k-d Search Skip List * k Raw destruct time (milliseconds)

n = 2,000 n = 10,000 n = 100,000 2 60 640 12770 5 90 1440 22080 10 180 2080 33940

Table A2 (a) Raw construct time for pass 2 of run 1 for testing the k-d Search Skip List I I I Raw construct time (milliseconds) l I I I Raw destmct time for pass 2 ofrun 1 for testing k-d Search Skip List k Raw destmct time(mil1iseconds) - n = 1,000 I n = 10,000 I n = 100,000

Table A3 (a) Raw construct time for pass 3 of mn 1 for testing the k-d Search Skip List 1 k 1 Raw constnict time (milliseconds) 1

Table A3 (b) Raw destruct time for pass 3 of run 1 for testing the k-d Search Skip List k Raw destruct time (milliseconds) naw wnsi;ruçr rime Tor pass 1 or run 4 tor testing the k-d Search Skip List k 1 Raw construct time (miIliseconds) 1

Table A4 (b) Raw destruct time for pass 4 of run 1 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000

2 60 830 15240 5 80 1700 22 170 10 150 2030 34370

Table A5 (a) Raw construct time for pass 5 of run 1 for testing the k-d Search Skip List 1 1 Raw construct time (milliseconds) 1 Table A5 (b) Raw destruct time for pass 5 of run 1 for testing the k-d Search Skip List I 1 1 k Raw destmct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 90 740 14290 100 1500 5 f 20420 10 130 2090 34850

Table A6 (a) Raw constnict time for pass 1 ofrun 2 for testing the k-d Search Skip List k Raw constnict time (milliseconds)

I 1

Table A6 (b) Raw destruct time for pass 1 of run 2 for testing the k-d Search Skip List 1 k 1 Raw destruct time (milliseconds) Table A7 (a) Raw construct time for pass 2 of run 2 of initial testing the k-d Search Skip List k 1 Raw construct time (milliseconds) 1

Table A7 (b) Raw destruct time for pass 2 of run 2 for testing the k-d Search Skip List 1 k 1 Raw destruct time (milliseconds)

Table A8 (a) Raw construct time for pass 3 of nin 2 for testing the k-d Search Skip List I 1 1 k Raw construct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 70 760 8990 5 110 860 14300

10 120 1540 22550 Table A8 (b) Raw destmct time for pass 3 of run 2 for testing the k-d Search Skip List I I i k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 70 1030 f 3590

Table A9 (a) Raw constmct time for pass 4 of run 2 for testing the k-d Search Skip List k 1 Raw construct time (milliseconds) 1

Table A9 (b) Raw destruct time for pass 4 of run 2 of initial testing the k-d Search Skip List k 1 Raw destruct time (milliseconds) Table A 10 (a) Raw construct time for pass 5 of run 2 for testing the k-d Search Skip List k 1 Raw construct time (rnilliseconds) 1

Table A 1O (b) Raw destnict time for pass 5 of run 2 for testing the k-d Search Skip List 1 k 1 Raw destruct time (milliseconds) 1

Table A 1 1 (a) Raw construct time for pas 1 of run 3 for testing the k-d Search Skip List k 1 Raw construct time (milliseconds) 1 Table A 1 1 (b) Raw destruct time for pass 1 of run 3 for testing the k-d Search Skip List I I 1 l Raw destmct time (milliseconds)

Table A 12 (a) Raw construct time for pass 2 of run 3 for testing the k-d Search Skip List k Raw construct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 30 680 9070 5 1O0 860 14060 10 110 1960 23560

Table A12 (b) Raw destmct tirne for pass 2 of run 3 for testing the k-d Search Skip List k Raw destruct time (milliseconds) n = 1,000 1 n = 10,000 1 n = 100,000 Table A13 (a) Raw construct time for pass 3 of run 3 for testing the k-d Search Skip List # Raw constmct time (milliseconds) I I

Table A 13 (b) Raw destmct time for Dass 3 of run 3 for testing the k-d Search ski^ List Raw destmct time (milliseconds) Table A14 (b) Raw destmct time for pass 4 of run 3 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 800 13940 5 70 1200 207 1O 10 100 2710 31240

Table A15 (a) Raw construct time for pass 5 of run 3 for testing the k-d Search Skip List 1 k 1 Raw construct time (milliseconds) 1

Table A 1 5 (b) Raw destruct time for pass 5 of run 3 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 630 15610 5 60 1230 20680 10 140 2120 31140 - Table A 16 (a) Raw construct time for pass 1 of run 4 for testing the k-d Search Skip List k Raw construct tirne (milIiseconds)

n = 1,000 n = 10,000 n = 100,000 2 30 470 9430 5 90 870 15190 10 130 1 940 22 170

Table A 16 (b) Raw destruct time for pas 1 of run 4 for testing the k-d Search Skip List t 1 i k Raw destmct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 600 14810 5 120 1240 19070

Table A 17 (a) Raw constmct time for pass 2 of mn 4 for testing the k-d Search Skip List 1 k 1 Raw construct time (rnilliseconds) Table A 17 (b) Raw destruct time for pass 2 of nui 4 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000

2 50 650 13980 5 1 O0 1370 21 170 10 130 1 2082 31210

Table A1 8 (a) Raw constwt time for pass 3 of run 4 for testing the k-d Semh Skip List r k Raw construct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 460 8850 5 70 1080 13800 10 170 1530 22510

Table A 18 (b) Raw destruct time for pass 3 of run 4 for testing the k-d Search Skip List , J k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 50 620 14270 5 110 1520 21150 10 190 2150 3 1120 Table A 19 (a) Raw construct time for pass 4 of run 4 for testing the k-d Search Skip List I 1 k Raw constmct time (rnilliseconds)

n = 1,000 n = 10,000 1 n = 100,000

Table A 19 (b) Raw destruct time for pass 4 of run 4 for testing the k-d Search Skip List I 1 1 lkl Raw destntct time (milliseconds) 1

Table A20 (a) Raw constmct time for pass 5 of run 4 for testing the k-d Search Skip List k Raw construct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 740 8960 5 70 880 12800 10 190 1620 23200 Table A20 (b) Raw destruct time for pass 5 of mn 4 for testing the k-d Search Skip List 1 k Raw destruct time (milliseconds) 1

Table A2 1 (a) Raw construct time for pass 1 of run 5 for testing the k-d Search Skip List k 1 Raw construct time (milliseconds) 1

Table A2 1 (b) Raw destruct time for pass 1 of run 5 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 60 1010 13640 5 1 O0 1370 19380 Table A22 (a) Raw construct time for pass 2 of run 5 for testing the k-d Search Skip List k Raw construct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 60 510 8530 5 80 860 13660 10 130 2240 22820

Table A22 (b) Raw destruct tirne for Dass 2 of run 5 for testing the k-d Search ski^ List lkl Raw destmct time (milliseconds) 1

Table A23 (a) Raw construct time for pass 3 of run 5 for testing the k-d Search Skip List k Raw construct time (rnilliseconds)

n = 1,000 n = 10,000 n = 100,000

2 50 520 8020

5 60 980 13210 1O 90 1600 24500 . Table A23 (b) Raw destnict time for pass 3 of mn 5 for testing the k-d Search Skip List f I 1 k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 640 14480 5 70 1630 2 1660 10 80 2080 32920

Table A24 (a) Raw constnict time for pass 4 of run 5 for testing the k-d Search Skip List k Raw construct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 40 500 8530 5 80 860 13480

10 160 1670 22640

Table A24 (b) Raw destruct time for pass 4 of run 5 for testing the k-d Search Skip List k 1 Raw destruct time (rnilliseconds) Table A25 (a) Raw constmct time for pass 5 of run 5 for testing the k-d Search Skip List k 1 Raw construct time (milliseconds) 1

Table A25 (b) Raw destmct time for pass 5 of run 5 testing the k-d Search Skip List 1 k 1 Raw destruct time (milliseconds) 1

-. Ta-ble - A26 (a) Raw construct time for pas i of 'run 6 for testing the k-d Search Skip List k Raw constmct time (mil1iseconds) Table A26 (b) Raw destruct time for pass 1 of run 6 for testing the k-d Search Skip List I k Raw destmct time (milliseconds)

n = 1,000 n = 10,000 ri = 100,000 2 50 780 13570 5 60 1580 29840 10 130 2750 31580

Table A27 (a) Raw construct time for pass 2 of run 6 for testing the k-d Search Skip List 1 1 k Raw construct time (rnilliseconds)

n = 1,000 n = 10,000 n = 100,000 2 70 550 9220

Table A27 (b) Raw destruct time for pass 2 of run 6 for testing the k-d Search Skip List k Raw destruct time (milliseconds) TabTable 1 A28 (a) Raw constmct time for ~asspass 3 of nrun 6 for testing the k-d Search Skip List -- - - k Raw construct time (milliseconds) l I I \ n = 1,000 n = 10,000 n = 100,000

2 70 540 8450 5 70 900 14060 10 110 1670 23300

Table A28 (b) Raw destmct time for pass 3 of run 6 for testing the k-d Search Skip List h 4 k Raw destruct time (rnilliseconds)

n = 1,000 n = 10,000 n = 100,000 2 70 690 13290 5 110 1140 19960 10 130 2640 3 1690

Table A29 (a) Raw constmct time for pass 4 of mn 6 for testing the k-d Search Skip List 1 k 1 Raw construct time (milliseconds) Table A29 (b) Raw destruct time for pass 4 of run 6 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

Table A30 (a) Raw construct time for pass 5 of mn 6 for testing the k-d Search Skip List Raw construct time (miliiseconds)

Table A30 (b) Raw destruct time for pass 5 of run 6 for testing the k-d Search Skip List k Raw destruct time (milliseconds)

n = 1,000 n = 10,000 n = 100,000

2 80 780 13770 5 120 1480 2 1940

10 180 2050 33860 Appendix B Average Construction and Destruction Time for Each Test Run of the k-d Search Skip List Table B 1 (b) Destruct time average for nin 1 of testing of the k-d Search Skip List 1 k 1 Destruct time average (milliseconds) 1

Table B2 (a) Construct time average for nin 2 of testing of the k-d Search Skip List 1 k 1 Construct time average (milliseconds) 1 \-, Destmct time average for run 2 of testing of the k-d Search Skip List 1 k Destmct time average (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 58 802 14020 5 94 1455 20292

.. 10 126 2400 32026

Table B3 (b) Destruct time average for run 3 of testing of the k-d Search Skip List k 1 Construct time average (milliseconds) Table B4 (a) Construct time average for run 4 of testing of the k-d Search Skip List k Construct time average (milliseconds) 1

Table 184 (b) Destmct time average for run 4 of testing of the k-d Search Skip List k 1 Destruct time average (miiliseconds)

Table B5 (a) Construct time average for run 5 of testing of the k-d Search Skip List I I k Construct time average (milliseconds)

n = 1,000 n = 10,000 n = 100,000

2 46 504 8360 Destruct time average for run 5 of testing of the k-d Search Skip List 1 k Destruct time average (milliseconds)

Table B6 (a) Construct tirne average for run 6 of testing of the k-d Search Skip List 1 k 1 Construct time average (milliseconds)

Table 86 (b) Destruct time average for run 6 of testing of the k-d Search Skip List k 1 Destruct t time average (milliseconds) Table B7 (a) Construct time average for al1 test mns of of the k-d Seaxh Skip List h Ikl Construct time average (milliseconds) 1

Table B7 (b) Destruct time average for al1 test runs of of the k-d Search Skip List k Destruct t ime average (milliseconds)

n = 1,000 n = 10,000 n = 100,000 2 57 774 13669 5 84 1373 20807 10 137 2324 32774 Appendix C Raw Insertion and Deletion Constant for Testing the k-d Search Skip List Insertion constant for pass 1 of run 1 for testing the k-d Search Skip List f 1

l Insertion constant

Table C 1 (b) Deletion constant for pass 1 of run 1 for testing the k-d Search Skip List 1 1 1 lkl Deletion constant 1

Table C2 (a) Insertion constant for pass 2 of run 1 for testing the k-d Search Skip List I I i IkI Insertion constant I Destruction constant for pas 2 of run 1 fi; testing the k-d Search Skip List k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 9.97 10.30 21-80 5 7.97 1 1.43 14.32 10 4.32 8.60 10.56

Table C3 (a) Insertion constant for pas 3 of run 1 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 13.28 9.97 15.05 5 5.30 6.38 9.37 10 5.98 5.12 8.44

Table C3 (b) Destruction constant for pass 3 of nin 1 for testing the k-d Search Skip List I 1 1 k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 9.97 16.78 25.45 5 5.32 9.97 14.79 10 6.3 1 6.74 1 1.36 - liiabl Livii ~VLIBLCUIL LUI pms * OLrun r ror resring tne k-CISearch Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 11.63 8.64 16.43 5 4.65 7.1 1 10.99

10 3.32 5.41 7.69 iI

Table C4 (b) Destruction constant for pass 4 of run 1 for testing the k-d Search Skip List t I i Destruction constant I I l

Table C5 (a) Insertion constant for pass 5 of run 1 for testing the k-d Search Skip List k I Insertion constant I 1 ame cs (b) Destruction constant for pass 5 of run 1 for testing the k-d Search Skip List k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 14.95 12.29 23.74 5 6.64 9.97 13.57 10 4.32 6.94 11.58

Table C6 (a) Insertion constant for pass 1 of run 2 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 9.97 8.97 14.33 5 7.3 1 7.24 9.05 10 5.32 7.4 1 7.3 1

Table C6 (b) Destruction constant for pass 1 of run 2 for testing the k-d Search Skip List I I 1 Ikl Destruction constant 1 Table C7 (a) Insertion constant for pass 2 of mn 2 of initial testing the k-d Search Skip List k insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 8 .O4 14.40 5 5.32 5.91 9.39 10 3.65 5.38 7.54

Table C7 (b) Destruction constant for pass 2 of run 2 for testing the k-d Search Skip List I I 1 Destruction constant I I I 3

Table C8 (a) Insertion constant for pass 3 of run 2 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 1 1.63 12.62 14.93 5 7.3 1 5.71 9.50

10 3.98 5.12 7.49 Table C8 (b) Destruction constant for pass 3 of run 2 for testing the k-d Search Skip List k Destruction constant

Table C9 (b) Destruction constant for pass 4 of run 2 of initial testing the k-d Search Skip L ist 1 k 1 Destruction constant 1 Table C 10 (a) Insertion constant for pass 5 of run 2 testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 8.64 15.05 5 4.65 5.85 8.77

10 3.98 6.54 7.33

Table C 10 (b) Destruction constant for pass 5 of run 2 for testing the k-d Search Skip List 1 k 1 Destruction constant 1

Table C 1 1 (a) Insertion constant for pass 1 of run 3 for testing the k-d Search Skip List k I Insertion constant I Table Cl 1 (b) Destruction constant for pass 1 of run 3 for testing the k-d Search Skip List 1 k Destruction constant 1

Table C 12 (a) Insertion constant for pas 2 of run 3 for testing the k-d Search Skip List k I Insertion constant

Table C 12 (b) Destruction constant for pass 2 of run 3 for testing the k-d Search Skip List I I 1 k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 13.12 23.28 Table C 13 (a) Insertion constant for pass 3 of run 3 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 4.98 8.97 14.52 5 3 -98 5.85 9.37 10 4.32 5.12 7.46

Table C 13 (b) Destruction constant for pass 3 of nin 3 for testing the k-d Search Skip List k 1 Destruction constant

Table C 14 (a) Insertion constant for pass 4 of run 3 for testing the k-d Search Skip List I I k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 9.80 15.93 Table C 14 (b) Destruction constant for pass 4 of nin 3 for testing the k-d Search Skip List I I 1 k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 13.29 23.15 5 4.65 7.97 13.76 10 3.32 9.00 10.38

Table C 15 (a) Insertion constant for pass 5 of run 3 for testing the k-d Search Skip List k I Insertion constant Table C 16 (a) Insertion constant for pass 1 of run 4 for testing the k-d Search Skip List I I Insertion constant I I I

Table C 16 (b) Destruction constant for pass 1 of run 4 for testing the k-d Search Skip List k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 9.97 24.60 5 7.97 8.24 12.67 10 4.65 8.84 11.61

Table C 17 (a) Insertion constant for miss 2 of run 4 for testing the k-d Search ski^ List I I Insertion constant Table C 17 (b) Destruction constant for pass 2 of run 4 for testing the k-d Search Skip List 1 Ik. Destruction constant

Table Cl8 (a) Insertion constant for pass 3 of run 4 for testing the k-d Search Skip List I I i k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 7.64 14.70 5 4.65 7.18 9.17

10 5.65 5.08 7.48

Table C 1 8 (b) Destruction constant for pass 3 of run 4 for testing the k-d Search Skip List I 1 lkl Destruction constant Table C 19 (a) Insertion constant for pass 4 of run 4 for testing the k-ci Search Skip List r k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 4.98 8.80 13.82 5 4.65 5.91 8.74 10 3.99 5.48 7.97 i

Table C 19 (b) Destruction constant for pass 4 of mn 4 for testing the k-d Search Skip List k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 8.30 17.44 21.59

5 4.65 7.97 13.06 10 3.65 7.5 1 10.74 l

Table C20 (a) Insertion constant for pass 5 of nin 4 for t&ng the k-d Search Skip List i k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 12.29 14.88 5 4.65 5.85 8.50 10 6.3 1 5.38 7.7 1 Table C20 (b) Destruction constant for pass 5 of run 4 for testing the k-d Search Skip List 1 k 1 Destruction constant 1

Table C2 1 (a) Insertion constant for pass 1 of run 5 for testing the k-d Search Skip List t I I k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 8.80 14.17 5 5.24 5.58 9.79 10 3.32 5.88 7.87

Table C21 (b) Destruction constant for pass 1 of run 5 for testing the k-d Search Skip List 1 k 1 Destruction constant 1 Table C22 (a) Insertion constant for pass 2 of nin 5 for testing the k-d Search Skip List k Insertion constant

Table C22 (b) Destruction constant for pass 2 of run 5 for testing the k-d Search Skip List i Destruction constant 1

Table C23 (a) Insertion constant for pass 3 of mn5 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 8.30 8.64 13.32 5 3.99 6.52 8.77 Table C23 (b) Destruction constant for pass 3 of run 5 for testing the k-d Search Skip List k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 10.63 24.05 5 4.65 10.83 14.39 10 2.66 6.9 1 10.94

Table C24 (a) Insertion constant for pass 4 of nin 5 for testing the k-d Search Skip List b k insertion constant

n = 1,000 n = 10,000 n = 100,000 2 6.64 8.30 14.17 5 5.32 5.7 1 8.96 10 5.32 5.55 7.52 Table C25 (a) Insertion constants for pass 5 of nui 5 for testing of the k-d Search Skip List k I Constant c for insertion averages I

Table C25 (b) Destruction constant for pass 5 of nui 5 testing the k-d Search Skip List k 1 Destruction constant

Table C26 (a) Insertion constant for pass 1 of mn 6 for testing the k-d Search Skip List k Insertion constant n = 1,000 n = 10,000 n - 100,000 2 6.64 9.30 13.69 5 3 -99 7.1 1 10.23 10 3.32 5.25 7.65 Table C26 (b) Destruction constant for pass 1 of run 6 for testing the k-d Search Skip List k Destruction constant

n = 1,000 n = 10,000 n = 100,000 2 8.30 12.96 22.54 5 3.99 10.50 19.83 10 4.32 9.14 10.49

Table C27 (a) Insertion constant for pass 2 of run 6 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 1 1.63 9.14 15.3 1 5 4.65 6.44 9.86 10 3.99 5.48 7.75

Table C27 (b) Destruction constant for pass 2 of nin 6 for testing the k-d Search Skip List k Destruction constant 1 Table C28 (a) Insertion constant for pass 3 of run 6 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000

2 11.63 8.97 14.04 5 4.65 5.98 9.34 10 3.65 5.55 7.74

Table C28 (b) Destruction constant for pass 3 of mn 6 for testing the k-d Search Skip List 1 k 1 Destruction constant 1 n = 1,000 n = 10,000 n = 100,000 2 11.63 11.46 22.07 5 7.3 1 7.57 13.26 10 4.32 8.77 10.53

Table C29 (a) Insertion constant for pass 4 of run 6 for testing the k-d Search Skip List 1 k Insertion constant Table C29 (b) Insertion constant for pas 4 of run 6 for testing the k-d Search Skip List k Insertion constant

n = 1,000 n = 10,000 n = 100,000 2 8.30 14.17 23.82

Table C30 (a) Insertion constant for pas 5 of nin 6 for testing the k-d Search Skip List I k I Insertion constant I Appendix D Insertion and Deletion Constant for Each Test Run of the k-d Search Skip List Constant for insertion average for mn 1 of testing the k-d Search Skip List k Constant c for insertion average

Table Dl (b) Constant for deletion average for run 1 of testing the k-d Search Skip List I 1 1 k Constant for deletion average

n = 1,000 n = 10,000 n = 100,000 2 1 0.96 12.75 23.50 5 6.25 10.44 14.41 10 5.18 7.18 1 1.23 Table D2 (b) Constant for deletion average for run 2 of testing the k-d Search Skip List k 1 Constant for deletion average 1

Table D3 (a) Constant for insertion average for run 3 of testing the k-d Search Skip List k Constant c for insertion average

n = 1,000 n = 10,000 n = 100,000 2 6.64 9.79 14.91 5 5.3 1 5.87 9.22 10 4.05 5.85 6.33

Table D3 (b) Constant for deletion average for run 3 of testing the k-d Search Skip List k Constant for deletion average

n = 1,000 n = 10,000 n = 100,000 Table D4 (a) Constant for insertion average for run 4 of testing the k-d Search Skip List k Constant c for insertion average

n = 1,000 n = 10,000 n = 100,000 2 5.64 8.97 14.64 5 5.44 6.46 9.1 1 10 4.85 5.58 7.6 1 ' i

Table D4 (b) Constant for deletion average for run 4 of testing the k-d Search Skip List k 1 Constant for deletion average 1

Table D5 (a) Constant for insertion average for run 5 of testing the k-d Search Skip List k Constant c for insertion average

n = 1,000 n = 10,000 n = 100,000 2 7.63 8.36 11.88 5 4.89 5.83 9.17 10 3.9 1 5.89 7.77 Table D5 (b) Constant for deletion average for run 5 of testing the k-d Search Skip List 4 1 k Constant c for insertion average I

n = 1,000 n = 10,000 n = 100,000 2 9.29 13.32 23.36 5 5.5 8 8.68 13.36 10 4.32 6.60 11.78

Table D6 (b) Constant for deletion average for nin 6 of testing the k-d Search Skip List k Constant for deletion

n = 1,000 n = 10,000 n = 100,000 2 9.96 12.96 23.33 5 5.7 1 9 .O3 15.10 10 4.65 8 .O2 10.70 Table D7 (a) Constant for insertion average for ail test nuis of the k-d Search Skip List k Constant c for insertion average

n = 1,000 n = 10,000 n = 100,000 2 8.02 8-98 14.25 h. 5 5.17 6.1 1 9.34 10 4.24 5.89 7.43

Table D7 (b) Constant for deletion average for al1 test rus of the k-d Search Skip List k Constant c for insertion average

n = 1,000 n = 1 0,000 n = 100,000 2 9.29 12.86 23.48 5 5.80 9.14 14.0 1 10 4.55 7.25 1 1 .O9 Appendix E Average Search Time for Each Test Run of the k-d Search Skip List Table E2 (a) The orthogonal range search time when dimension k= 2, size n = 104 area ratio # nodes found the search time in 5 passes (millisecond) average time Table E2 (b) The semi-infinite range search time when dimension k = 2, size n = IO4 1 ( area ratio 1 # nodes found 1 the search time in 5 passes (millisecond) 1 average tirne 1

Table E3 (a) The orthogonal range search time when dimension k= 2, size n = IO5 1 area ratio 1 # nodes found 1 the search time in 5 passes (millisecond) 1 average tirne 1

Table E3 (b) The semi-infinite range search time when dimension k = 2, size n = 105 I 1 I I 1 1 area ratio 1 # nodes 1 the search tirne in 5 passes (rnillisecond) ( average time 1 --- - . \ -1 The orthogonal range search time when dimension k= 5, size n = 1O3 * area rat # nodes found the search time in 5 passes (millisecond) average time

0% O O O O O O O

10% 6 1 O 1O O 1O O 4

30% 264 O O O O O O

50% 462 O O O 10 1O 4

80% 795 O O O O O O

100% , 994 i O 10 O O O t 2

Table E4 (b) The semi-infinite range search time when dimension k = 5, size n = IO3 area ratio # nodes found the search time in 5 passes (millisecond) average time

0% O O O O O O O

36.0 1% 198 O 1O O 1O O 4

38.71% 347 1O 1O 10 10 10 1O

74.27% 62 1 1O 1O O 10 O 4

9 1-43% 872 O O 1O 10 O 4

100% 995 10 1O O O O 4

Table ES (a) The orthogonal range search time when dimension k= 5, size n = IO4 1 area ratio 1 # nodes found ( the search tirne in 5 passes (millisecond) 1 average tirne Table E6 (a) The orthogonal range search time when dimension k= 5, size n = 105 1 1 I I i 1 area ratio 1 # nodes found ( the search tirne in 5 passes (millisecond) 1 average time 1

Table E6 (b) The semi-infinite range search time when dimension k = 5, size n = 1 Os I 1 I i 1 area ratio 1 # nodes found 1 the search time in 5 passes (millisecond) 1 average tirne 1 Table E7 (b) The semi-infinite range search time when dimension k -- 10, size n = IO3 area ratio # nodes found the search time in 5 passes (millisecond) average time ' O O O O ----O 1O O 4 20 f O 1O 1O

1O 1O 1O 10

87.92% 832 O O O 1O O 2

100% 990 1O O O O O 2

Table E8 (a) The orthogonal range search time when dimension k= 10, size n = 1O4 area ratio # nodes found the search time in 5 passes (millisecond) average time

0% O O O O O O O

10% 884 1 O0 70 70 80 120 88

3 0% 2897 70 90 80 8O 1O0 84

50% 4950 150 90 1O0 90 90 104

80% 7999 120 110 120 180 1O0 126

100% 9997 90 110 , 120 90 130 108 The serni-infinite range search time when dimension k = 10, size n = 1 O4 I 1 I I 1 1 area ratio 1 # nodes found 1 the search time in 5 passes (rnillisecond) 1 average time 1

Table E9 (a) The orthogonal range search time when dimension k= 10, size n = IOS L 1 area ratio 1 # nodes found 1 the search tirne in 5 passes (rnillisecond) 1 average time 1

Table E9 (b) The semi-infinite range search time when dimension k = 10, size n = 10' I I I 1 I 1 area ratio 1 # nodes found 1 the search time in 5 passes (millisecond) 1 average time 1 The average orthogonal range search time (milliseconds) for the k-d Search Skip List % of points in range 0% 10% 30% 50% 80% 100% 1 Average search time in milliseconds

Table E 1 1 The average semi-infmite range search time (milliseconds) for the k-d Search Skip List I 1 1 1 I % of points in range 1 io%orless 1 40 to 60% 90% or more 1 k 1 #points 1 Average search time in milliseconds

------

A Appendix F Half-Space Range Search Time for Each Test Run Table F 1 The half-space range search time (milliseconds) when dimension k = 5, size n = IO4 equation of the hyper plane #pts found search time Inodes % 1 X, + X: + 10x3 + 15x4+4x5=16 18x, + x2+ 13x, = 9 7xl - 2x2 + 10x4 - x5= 6 7x1+ 4x, - 2x, - x, = O 93 il + i7x2+ 3x1 + ~SX,+ 18xs =-17 - X, + 7x3 + 2x4+ 17xs= 10 Ix, + 12x,+ 1 lx, + 17xs = 2 cl + 3x2+ 16x3- x, + 16xs= 16 SX, + 12x2+Sx,+ i8x4+ 15x5=4 3x1 + 14~,+ ~OX,+ 5x4+ 15x5= 18 K, + 17x2+ 14x3+ 14x4 + 14x.j5. IO BxI -x.,-x,+ X, + 1Sx5=3 DxI+ 2x,+ 9x4+ 12x5= 17 , +2x2+7x3+ 18x4+ 12x5=9 4xI +5x1+ 12x3+ 5x4+ 1lx5=2 x, + 7x5 + 16x3 + 13x4+ 10xs= 16 6xl + 3x2 + 15~~+ IOx, + 9xs = 13 x, + 6x2 - x, - ZX, + 8x, = 5 2xl + Zx, - 2x3 + 16x4+ 7x, = 2 X, + 13x2 + l2x, +x4+ 6x5=4 lx, + X= + 3x3 + 2x5~18 ;XI + 2x2 + 17x3 7xq = O Sx, + l6x, + 4x4 =l7 ox, + x2+ 15x, + 12x, = 10 !x, + 3x2 + 4x3 - xs = 2 i5xI + 6x3 + 9x3 + 8x4- 2xS=16 )x, + 15~~- x3 + 6x4 + 18xS=4 cl + 17x2 + 2x3 +15x4 +17xS =18 14x, - x2 + 7x, + 2x4+ 17x, =10 jx, + x2 + 1lx, + lOx, + 16xS=2 -2x, + 9x2 + 9x4+15 X, =12 13xI + 12x2 + 5x3+ 17~~+ 14x5=4 2x, + 8x2 + 4x3 + 14x4+ 13x5=I lSx, + lOx, + 9x, + x, + 13x, =15 7x, + 13x2 + 13x, + IOX, + 12x5=8 18xl -t 9x2 + 12x3+ 7x4+ 1 lx, =5 6xI + 5x1 + 1lx3 + 4x4 + 1OxS=2 X, + 14x2 + 2x4 + 9x, =11 IIx,+ 10xt + 8xS=8 3xI t- 12x2 + 4x, + 8x4 + 8x5 =I 16x, + 15x2 + 8x3 + 17x, + 7x5=14 I lxl + 2~~ - 2x, + ~SX,+ 6x5 =2 4x, - x2 + 17~~+ l2x, + 5x, =O 15x, + 7x2 +6x, + llx,+ 5x,=9 7x, + 9x2 + 1 lx, - X4 +4x5=1 2x, + 18x2 + l8x, + 4xr =10 15x, + 4x3 + 5x, + 3x, =3 r riç II~U-S~W~:iarigt. scarçn rime (mirliseconas) when cilmension k = 5, size n = IO4 - .. - equation of the hyper plane #pts found search time nodes %

12x1+ 16~:+ 15~~- 2~~=l4 x, + 15x2 - Sx3 + 5x, + L7xs =4 15 21 -X 1I

3x1 + 3x3 + 16x4 + 17xS=O 2x1 + 8x2 + 13x3 + 15x4+ 16xS=9 K, + 1lx2 + 17x3 + 2x4 C 15x5=1 (1 - X? + 6x3 + 15x5=10 4x1+ 7x2 + 16x3 + 14~~=-1 x, + 9x2+ 7x, + 14x5=12 , + 18x, + 10x3 + 16x4+ l3xS= O 3~,+14x3 14x4+ 12x5=14 X, +2x2 - x3+x4+ 12x5=6 2xl + 4x2 + 2x3 + lOx, + 1lxs =O xl + 9x2 + 1lx, + 5x4 + 9xs=5 8x, + 18x2 + 4x, + 9x, =l4 1x1+ 18x2 + 1lx, + 14x4- x, =3 6x1+ 15x3+ x, + 18x5=17 .6x, + 4x2 + 3x3- Zx, + 17xS =2 10x,+ 2x3 + 15x4 + 16x, =O Ux, + I 1x2 + 17x3 + X, + 14x5=1 >xi + 13x1+ lOx, + 14x, =15 17x1 + 3~~ +15x1 + 17x4 + 12xS=17 3xI + 6x2 - X) + 4x4+ 12xs=9 -2~1+ 2x2 - 2x, + x4 + 11x5 = 6 lOx, + 4x, + 2x3 + 9x, + lOx, =O 2x,+ x, t 6x4+ 9x, =l7 10xl + X, - 2x4+ 2x5=14 2xI + 3x2 + 4x3 + 5x4+ x5=6 15x1+ 6x1 + 9x3 + 14x4+ X, =-1 -xl + 1lx, + 18x3+ lOx, =5 12xl +x13? ix, + l8x, - x,=-2 3x1+ 15x2 +6x3+5x4- 2x5=ll 16xl + 18x: + 10x3+ 14x4+ 18xs=4 5x1+ 14~:+ 9x3+ I lx4+ 17xS=1 -2~~+ 16~- + l4x3- X, + 16x5= 15 IOxI - SX, - 2x3 + 6x4 + 16x5=7 2x1+ 2x3 + 15x4+ 15x5 =O 18x, + 9x, + 12x3+ 13x, + 14xs=9 9xt + 1 1x2 + 17x3+ 14x5=1 4x1- XI + 5x3+ 13x5=10 LW ilail-syac;t:range searcn rrme (rniiliseconds) when dimension k = 5, size n = 5* 104 Oequation of the hyper plane #pts found lxl +4x3+ 8x5= 8 (, + 13x1 + 13x3 + 12x4 + 2x5 =17 lxl + 7x2 - 2x3 + 1 lx4+ 12x5=11 cl - 2x2 + lOx, + 9x4 + 4x5 =9 4x, + 14x2+ 4x4 - x, =O equation of the hyper plane #pts found search time

(1 + 16x2 - 2x3 + 18x4+ 9xS=14 t, + 7x2 + 10x3 + 14x4 =13 jx, + 16x2 + 9x,+ 8x, =1S irl -x2 +9x3+x4+6xS=l5 5x1+ 8x1 + 17x3+ 11 x, - x, =O K, + 10x, f 12x3+ 18x4+ 14x5=6 xi + 18x2 + 13x3 + i4x, + 10xs-8 K, +4x2 + 5x3 + 18x4+6x5=7 2x1+ 1 lxT + 8x3 + 1Ox4+ 14x5=17 xi + 15xz - x, + 2x4 + 4x, =9 1 -2x2+ 14x4+ 1lx5=16 r, + 17x2 + l6x, + 18x4+- 5x5 =-1 XI - X? - x, + 4x4 + 4x, =12 X, + 2x2 + 10x3 + 17x4 + 15x5=4 2xl + 14~~+ 2x3 +15 X, + 7x5 =2 XI + 14x3 + 10x4 - X5 =-1 Ix,+ ~SX-,+ 17x4 + 14x5=17 !xl + 4x2+ 6xs =14 lxl 3- 2x, + 5x3+ 16xS=11 ;xl + llx-, + 2x3 - x4+ l8xS=6 1x1+ 12x2 + 10x4 1OX, =2 i lx, + X? -t 16x3 + 9x4 + 17x5 =12 ~OX,+ 16x2 + 16x4+ 1 lx, =10 !XI + 14x2 + 15x3 - 2x4 + 4x5 =14 14x, - x2 + 11 x3 + 15x4 + 5xs=6 1 lx, + 18x, - 2x4+ 16x5=6 1 1x1 + 15x2 + 1 1x3 - 2x4+ 8xS=7 7xI- xi + 1 lx3+ 5x4+ 1 Ix5=14 12x1 + 16~~+ 8x3 + 13x4+ 2x5=8 lOx, + 16x2 + 7x, + 1lx, =8 17x1+ 15x2 + l0x3+ 15x4+ 17x5=-1 1 lx, t 8x2 + 16x3+ 2x4 + 13x5=l7 16x1 + 15x2 - x3 + 3x4+ 5xS=9 lSx, + 1lx? + 8x, + 10x4+ 14x, =17 lOx, + 14x2 + 2x, + 8x4 + 2x5=-1 -XI + 12x2 + l6x, + 2x4+ 1lx, =O 14x, + 5x3 + 7x4+ 14xs=12 3x1 11 x-, + 18x3 + 4x.4 + 5x5 =Io 17x1- X2 + 7x3 + 1 1x4 lOxS=2 17x1 + 16~-- x4 + 2xS=-2 7x1- 2x2 + 15x3+ 16x4+ 1Ox5=1 8x1+ 10x3 + 4x5= 8 IOx, - 2x3 + 6x, =15 18x1 + 6x. + 4x3+ 7x, - 2xs= 18 13x1 + X, + 13x4 + 9x5 =9 Ilx,+ 12~:+9x3 -2x5= 18 The half-space range search tirne (milliseconds) when dimension k = 5, size n = los equation of the hyper plane #pts found search time nodes % 16.9% 1

x, + 18x7 + 3x3 + 12x4 +4x5 =1 7xI-+- IlxZ+8x3 + 10x4+ 14xS=I7 7x, + l0xz + 13x3 + 3x4 - 2xS=10 6x1+ 3x2 + 8x3+ 3x5=18 lx, + 5x2 + 14x3 + 17x4 + 8xS-14 0x1 - x2 f 9x3 + 14x4 + 14x5=1 XI + 9x2 + 3x3f 8x4 - 2xs=7 3xI + 11x2 - x3 f 14x4 + 13xs=14 Oxl + I lxt + 7x3 + 15x4+ 1SxS=O 6xl + 12x2 + 5x3 -1- 12x4+ 12x,=O lx, + 8x2 + 3x3 + 7x4+ 8xs =-2 .OX, + 8x2 + 4x3 + 18xS 4 rx, + 8x2 f 13x3 + x4=1S )x, - x, +7x3 + 16x4+4x5=18 12x1+ 5x2 + 10x3 + 9x4 + 12x5=6 exI + 5x2 - x4 =17 L5x1+ 6~~+ 9~3+4xS =3 .XI+ 14x3 - x4+ i4xS=l8 lOx, + 12x, + 14x, + lOx, + 3xs =-1 .xl - 2x2 + 9x3 + 10x4+ 14x5=4 6x, + 5x2 + 5x, + 5xs=O 18x, + 10x2 + 14x, + X, + 7xs=I5 x, + 13x2 + 7x3 - 2x4+ 15x5=18 1lx, + 18x3+ 4x, - xS=10 13xI + 8x3 + 14~~~3 14x, - x- + x, + 4x, =7 18x, - x, + 9x, + 2x, + 8x5=15 8x1 + 5xj + 17x4+9xs =4 6xl + x, + 2x, + 18x4+ 14xs =18 1lx, + 7x, + 8x, + l7x, =l7 14x1 + 7X2 + 9x3 4x.4 +5 Xs =O 12x1 + X2 X3 + 17x4+ 12~~=-2 9xI + 17~~+ 14x3+ 8x.4 - X' =16 18x, + 16x, + 7x, + 3x, + 7x, =16 10xl + 12~~+ 7x3 + 8x4 + 12x5=17 18x1+ 2x2 - X, - 2x4- 2x5=11 13x1+ 13x2 + 3x3+ x.4 + 12x5 =6 4x1 + 17xS+ 13~~ + 1 5x5 -9 The half-space range search time (rniiliseconds) when dimension k = 5, size n = 1Os 1 equation of the hyper plane #pts found search time

+ 14~~+ 12x3 + 5x4 5x5=1 lxl + 6x2 + 1 lx, + 7x4+ 9~~=O ixI +4x2 i- 15x3 -x,+ 1lxs=14 lxl + 7x2 + 8x3 + 17x4=17 7x1 + 13~.+ 15x3 + 15x4 + 5xS=16 3xl + 5x, i-x4 + 1 lxs=8 ., + 6x, + 1 lx, + 17x, =7 U, + 1lx2+ 10x3 + 5x4+ 4x5 =3 2x, + 18x2 + 13x3 - x, + 12x5=12 1 + 7x2 + 7x3 + 14x4+ 17xS=18 3x, + 13x2 + 3x3 + x, + 12x, =6 X~ + 5x2 + 13x3 + X4 + 1 lx5=-2 4x, -t 5x, + 12x, - x, + 7x, =-1 Sx, + 5x2 + 1 lx3+ 18x4 + 5x, =- 1 , + 4x2 + 14x3+9x4 + 7xS= 13 XI + 7~~ + 16~~.x4 f 13xS=-1 KI + 3x2 + 16x3 + 4x4 - 2xS=O xl + 10~:+ 9x3 + 8x4+ 17xS=-1 2xl t 13x2 + x3 + 18x4- xS=-2 7x1 + 9x2 + x3+ x.4 -k 2x5 =-1 lx, + 13x2 + 1 lx, + 5x4+ 7x, =8 Ox, + 2x, - xz =3 lx, + 15x3+ 7x4 =O X, + I~X, + x,=11 I~x,-x, + 17x3+3x4+ 1IxS=8 ?xl + 17x2 + XI + 4x4 + x5 =4 cl + X? + 14x3 + 6x4 + 14x5 =12 15x, + 15x2 + i8x3+ 1lx, - x, =8 lxl + 4x2 + 13x3 + 5x4 + 3xS=13 5xl + 9x2 + lOx, + 2x4+ 5x5=5 17xl + 7x2 + 16x, + 4x4 + 16x, =2 9x1 + 12x3+ IOX, + 7x, =14 12xl + 3x2 + 16x, + 9x, =3 ~OX,+ SX, + 9~~+ 7x4+ 9x5 =6 9xl + 15x, + 5x, + lOx, =l5 lox, - x, + 2x3+ 13x4+ x, =O -2xI -t- 9x2 + 6x3 + 17x4 + 15x5 =l 5 14x, + i3x2 + 7x3 + 18x4+ 14x, =-2 2xl + 9x2 + 16x3 + 10x, + 5x5 =9 8xI + 12~,-i- 17x3 - X, + 1OxS=16 3xl + 15x2 - Zx4 + 3x, =5 9x, + 8x, + 7x, + 2x, + 1 lx, =IO 8x1+ 17x, + 6x3 + 9x4+ 18x5=8 18xl + 6x, + lOx, + 5x, + 6x, =O 3x1+ 17x1 +5x3 +8x4 +17x5=9 A UVIY I. 1 The half-space range search time (milliseconds) when dimension k = 7, size n = IO4

equation of the hyper plane #pts found search time nodes Oh cl + 2x2 + 14x3 + 3x4 - xS+ 6x6+ 13x7= 16 h ?XI+5x2 +6x3 + 5x.4 +16xS+2x6+x7= 17 !lxl + 4x2 + 10x3+ 10x4+ 14x5-t 13x, + 1lx, = 4 ~,+15x~+3x,+17~~+13~~+15~~=6 lx, + 15x2 +2x3 +8x4+6x,+ Ilx,+7x7= 1 6x1 + llx3-t 3x4+ 5x5+ 18x6+7x7= 17 XI + 4x2 + 3x5 + 2x6 + 6x7 = 11 6x, + 3xc + 10x3 - 2x4+ 17x6+ 15x7= 2 6xl + 17x2 +9x, -t- 13x4+ 18xs+ llx,+ 15x,= 1 xl+5x2 +6x3+4x4+ 15xs+2x6+ 13x,=11 XI+ ~OX,+ 15x3 + 14x5+9x6+ 13x7=5 x, + 2x2 + 13x3+ I~x,+ k2x, + 3x6+ 12x7= 5 Zx, - x2 t l2x, + 12x4+ 1 lx, + 12x7=15 xI+3x2 +7x4+9x5+6xo+ llx7=9 1 + 17x2 - X3 + 2x4 + 7x54- 10x7 = 9 lx1+ 7~~ - 2xd+ 6x3+ 7~,jf 10x7 = 3 7x1+ 9x2 + 17x3+ 17x4+ 5x5 + 16x6 + 9x7 = 8 Ix,+5x2 + 16x3 + 14x4+4x5+13x6+9x,=-2 .6x, + lOx, + 4x, 4 10x4+3 x, - x, + 8x7 = 13 ,8x1+ 9x2 7x3 + 15x4 X5 + 9x6 - 2x7 = 0 )x, + 11x2 + 12x3 + 2x4+X6+7x7= 18 lx, + 17x, + 10x4+ 13xs+ 4x6 + 1sx7= 7 17xI - X2 +3 x3-2x4+ 12x5+ l8x6+4x7=4 7x, + 6x, + 4x, + 15xd+ 8x, + 13x7= O l4x, + 9x2 + lïx, -i-16x4 + 4x, + 16x6+ x7= 2 .2x, + 14X7 +4x3 + 12~~+3~,+X,=18 7x1+ 13x2 + 8x3 + 17x4 + x,+ 12x6+ IOx7=4 7x, + 2x, + 2x3 + 3x4+ 14x, = 6 14xl + 14x2 + 16x3 + lOx, - x, + 15x, + 9x, = 8 9xl + x2 + 5x3 + 9x4- x5 + 3x6+ 9x7= 14 1lx, 4 9x, + 14x4 + 18x5+ 14x, - x7 = 0 -xl + 2x2 + 4x, + 13x5+ 17x7= 9 14x, + 7x, +5x,+ llx, + 10x6+6x7= 17 16xl +9x2 + 18x,+3x4+ fox,-x,+5x,=O 3x, + 1lx, + IOx, + 9x, + 16x7= 3 l3x, -t 16x2 + lOx, + 7x4+ 8x, - îx, + tSx, = 13 18xI -x, +3~~+6~~+3~,+15x7=7 4xI + 1lxi + 13x3 + 10x44- 5x5 + 5x6 +3 X7= 10 9xl + 16x2 + x3 + 6x4 +4xs + 11xo+ 3x7=4 3x, + 3x2 + 1 lx3+ 4x4 + 3xy+ 3x7= 9 16x, + 5x, + 15x, + 13x4+ 2x, + 13x,+ 13x7= 6 2x1+ 17x2 +9x3-x4+x5+15x6+2x7=8 18xI + 18~~+ L~x, + lSx4- 2x6+ x7= 13 12x, + 5x, + 6x3 + ]lx4- x,+ 6x,+ x7= -2 9x, + 12x7 - x, + 15x4+ 17x5+ 5x, + iox, = 10 SX, - X? + 12x3 - X, + 15x5 + 4~~= 1 13x, + 6x2 + 3x1 + 14x4-t- 6x, + 17x7= 9 k = 7, size n = 104 search time nodes %

., -t 17x2 + 7x3+ 9x, +14x, + I~x,+ 14x7 = 13 cl + 13~-+ 6x3 6x4 + 13xS+ 9x6 + 14x7= 2 , + 16x2 + ~OX,+ 15~~+ 12x5 + X, + 3x7 =O 3x, - Sx, + i5x3+ 2x4-t 1 Ix,+ l5x, + 13x7= 17 YI -X3 + 10x4+ 11x5+7xA+2x7=15 K, + 8x2 + 8x3 + 9x4+ 10xS+ 17x6+ 2x7 = -1 K, + 4x2 + 7x3 + 6x4 +9 xs + 14x6 -t xi = 9 x, + 13x2 + 18x, + 4x, +9 x, + 2x, + x, = 14 4x, + 9x, +17x, + x, + 8xs + x, = 3 x, + 5x, + i6x3-x, +7 x, + Iix, = 13 6xI+8x, +7x4+6x,+ 1Ox,+ llx7= 10 X, + 4x2 - X, + 4x4+ SX, + 7x, + ~OX,= O X, + 13x2 + 8x3+ îx4+4x5 + x16,f 10x7= 5 OX, + 9x1 + 7x,+ 3x, + 13x,+ 10x7= 15 lx, + 5x2 + 16x3 + 8xS+ 17x6+ 9x, = -1 lx, + 1lx2 + 12x3+ 9x, +3 x, + 5x, + 7x7= -2 x1+7x2+ 11x3 +6x4+2x5f 2xof 7x7=7 4x, + 16x, + 4x4+ 2xs +12 x,+ 7x7= 13 ix, - 2x, + 4x3 + 13x4+ x, + 4x6+ 1ïx7= 10 .6xl + 14x, +3x, + 10x4+x,+ 17x7=0 Ix,+ 17x2 + 8x3 + l8x, + 15x6+ 6x7= 17 x, - X, + 13x3 + 5x4+ 8x6+ 1 6x1 = 14 13xI + 17~,+14x4-x5+5x1= 12 jx, + 3x2 + x, - 2x, + 14~~+ 16x, = 9 jx, + 16x2 + 3x4+ x, + 12x6- x, = 6 14x, + 6x2 + Mx3+ lOx, + l4x, + 8x7 = 9 7xl - Zx, + 17xs+ llx, +7 x7= 13 17x, + 16x, - x, + 16x4+ 16x, + 8x, + 6x, = 2 16x, + xi + 16x, + 4x4 + 12x5+ 18x, + 5x1 = 1 ~OX,+ lOx, + 4x, + îx, + 11 x, + 6x, + 4x7= 6 2x1+ 12x2 + 9x3 + 1 lx4+ 10x5- X, + 15x7= 3 15xl + t5x2 + 14x, - x, + 10xs + lZx, + 4x7= O 14x, + 7x, + 12x3+ 13x, +8 x, + 6x, + 3x, = O llx, +5x2 + 15x,-x4+6x,+ 17x,+ 13x,=7 8x, + 8x2 - x, + 6x, + 5x, + IOx, + 2x, = 4 -2x1 + 4x2 - 2x3 + 3x4+ 4xS+ 7x6 + 2x7= 15 13x, + 13x, +8x3+2x4+4x,+ 16x,+x,=-1 -x, + 16x1 + 3x, + 12x, + 1 lx, = O 16xl + 2x, + lSx, + 7x, - x, + 1lx, = 13 13x, + 9x, + 5x, + 1 lx, + 17x, + lOx, + 9x, = 4 7xl + lox, -1- 14x3 l- 3x, +15 x, + 13x, + 8x, = 9 x, -x, +ZX,+~X,+ 14x5+x,+8x,=14 The half-space range search tirne (milliseconds) when dimension k = 7, size n = 5* IO4 equation of the hyper plane #pts found s nodes %

12x1 + 4~~ + 8x3+ 8x4 + 12x5 + 13x6 + 6~7=6

(, + 12x2 - XI + 15x4+ 17x5+ 5X6 + 10x7= 10 5x1 + 9~:+ 5x3+ 5x4 f 14~~+ 5xo + 9x7 = 3 !x, + 5xz + 16x3 + 8xs+ 17x6+18 x7=4 , + 13x1 + 17x3+- 17x4+3 x, - x, + 18x7 = 16 3xI + 17~3-t14x4-xS+5x7= 12 r, -t 8x, + 12x4 + lSx, -1- 14x6+ 14x7= 2 lx, + 16x2 + 9x3+ 5x4+ 5xs - 2x, + 1lx, = 16 K, + X, +5x, + 15x4+x5+ 7x6+ 9x7= 15 x, + 15x2 + 1 lx, i-2x4 +18x5 + 5x, + 7x, = -2 7x, + 9x, + 18x, + lOx, +14 x, + îx, + 5x7= 1 2xI + 8x2 + 8x3 + 8x4 + 9x5 + 17x6 + 15x7 = 13 X~ + 18x3 +3xS+ 4x6+x7=4 ZX, + 17x3+ 12x4+ 18xs + 9x7= O .x, + x2 + lSx, + 3x4+ 1lx, + 18x6+ l7x, = 16 lx, + 5x2 + 15x3+ 18x4+5 xs + 17~,+ 4x7 = 1 3x, + 12x2 + 10x3+ 17x, + Sx, + 7x7= 8 lxl + 17x2 + 6x3 + 8x4 + 13x5 + 12~~+ 5x7= 6 3x1-xz +x3+ 15~~+8~,-2~,+3~,=16 .6x, + 2x2 + x3 + 9x4+2 xs+ 18x6 + 12x7 = 1 )xl+ 13x2 + 6x,+ 14x4+ 18x5 + l2x,+ lOx,= 15 14x, + 14x2 + 5x, i- 5x4 + I 1x, + 9x, + 18x7 = 11 2xI+5x, + ~SX,+ 18~~+5~~+17~,+4~,= 1 lSx, + x, +4x, + 13x,+ 7x,+ 13x7= 2 $x, + 15x2 +x, -x, + 12~~-x6= 18 Zx, - 2x3 + 8x4 + 8x, + 8x6 - 2x7= 17 3xI + 12~~+ 8x4 + 4xS+ 13x6+ 7x7= 3 18x, + 5x2 + 5x3 + 16x4+ lOx, + 5x7= 7 ~Ix,-x,+~IX,+~X,+ 17~~+8~,+3~~=11 17~,+ 15~~+ X, - X, + 1 lx5- X, + 12x7 = 12 -2x1+ 6x2 + 2x3 - ZX., + 8xr + 3~~ = -2 17x, + 12xz - x3+ 7x4+ 4x5 + 13x6 - x7= 18 2xl + 8x2 + 9x3+ 2x4 - xs + 3x6 + 7x7=-2 llx, +9x2 +4x3 + 9x4+ 15xS+ ~OX,+ 5x7= 7 -XI+ 1 lx2+ 15x4 + ~OX,+ L~x, + 3x7= 16 15x, + 1 lx, + 1 fx, + 13x, + 5x, + 10x, + 12x7= 7 \4x1 + 7x2 + 8x4 + 12x7 = 2 18x, + 8x2 + 7x, + 13x4 + 1 lx5- 2x,= 2 6xl + 10xz + 2x3 - x, + 6x, + 6x, + 17x, = 11 -x, +17x2 + 6x3 - X, + 14x7= 15 2x, + 14x2 + I~x,+ 1 lx, + l7x5+ 13x7= 8 14x, +x2 + 14~,+8x,+ 13x5+x,=3 + MX, + 4~,+ 3~, + 7x, + I~X, +9 x7 = 5 2xl + 7x, + 9x, + 8x, + 2x5+ 7x, + 7x, = -1 when dimension k= 7. size n= 5*104 equation of the hyper plane #pts found nodes % Table F 1 1 The half-space range search time (milliseco ~ds)when dimension k = 7, size n = IOS equation of the hyper plane iodes % jxl + 12x2 + 13x3+ 9x5 + 6x6+ 16x7= 0 3x, + 18x2 + 7x3 + 18xs + 13x,i- 14x,= 8 1x1 +5x2 +9x3 +4x4-x5-2x6+6x7=3 K,+ x3 + 17x4+SX, + 16x,+ 11x7= 7 xI-tx2 +6x3+ 13x4+11x5+ 12x6+5x7=Z 4x, +6x2+ 5x3 -2x4-xf + 8x6=4 lx, + ~OX,+ I6x3+ lOx, + 9x, + 17x7= 1 7x1+ l0xz + 5x3 - Xs 4- 1 1x6 + 13x7 = 9 6x, + 13x, + l8x, + 8x.3 + 14x6- 2x, = 13 7x1 -x, +6x4+ l8xS+13~,+ 14x7=5 XI + 7x2 + X3 + 4x5+ X6 - X7 = 3 lx, + x, + 10x4+ 15x, + 2x,+ 16x7=6 2xI +5x2+ 18x3+ 11~~+4~~+8~~+~~=0 4xI + 3x2 + 2x3 + 13x4+ lSxS+ 5x6+ 7x7 = 11 OX, + 12x3 + 3xS+ 13x6 + 3x7= 7 6x, + 13x2 +3x4+ llx, + 18x6- x,= 14 lx, +2x2 +3x, +9x,+ 3x7= 3 5xI + 16~~+ 11x3 +3x4+ 7xS+ 14x6-x7=10 . 0x1 + 4x2 - 2x3 + 5x4+ 14x5 + 16x6 + 14x7 = 6 ix, t- lOx, + 17x3 + 3x4 +- 18x, + 8x6+ 13x7= 15 lx, + 12x2 + 10x3 + 6x, + 1 lx6-xi= O !x,+7x2 + 2x,+ 13x4+14x,+9x,+3x7= 3 1 Ix, + 13x2 + 18x3 + 14x4+3 xs +15x,+ ~OX,= -2 jx, + llx, + 3x, + 16x4+14 xs + 12x6+ 16x, = 7 17x, + 2x, + 3x3 + 6x4 + 3x, + 13x6+ 12x7= 10 16x1 + 5x2 + 18x3 + 3x4+ 13x, + 16x, - 2x7= 14 2xI + 17~~+ 9x3 + 13x4 - X, + IIx, + 2x7 = 8 7x, -2x, + l6x, + 18x4+ 10xs+ 1lx6+9x,=8 -x, -x, + 16x3+ 14x4+ 17x5+ 16x6=-1 10xl + 4x2 + 12x3+ x4+ lZx, + 4x, +l lx, = 12 18xl + 8x2 +- 5x4 + 16x5 + 14x, + 15x7 = 4 17xI + 15~~+ 15x3+ 18~~- X, + 17~~ + 8x7= 15 x, + 7x2 + 2x3+ x4 + 7x, + 3x7= 1 8x, + 7x, + 13x3 + 1lx, -t 17x, + 1 lx, = 8 l0xl+ 11x2 + 15x3+x,+3xs+ 18x,+4x7= 18 12xI + 2x2 + 15x3 + 13x4 + 13x5- X, = O 16x1 + 9x2 + 18x3 + 6x4 + 8~~ + 5x7= -1 l5~,-x, + 14x3 +9x4+ 1lxs+ 17x6+ 12x7~3 16x, + 7x2 + i3x, + 18x4+ 15x, + 7x, = 16 2x, -+- 8x2 + 16x4+ x6-x7 = 15 14x1 + 7x4+ 1lxs -t 3x6 + 15x7 = 17 4x1 + 18x, + 17x3+ 7x, +17 x, + i4x, -+ 9x7= -2 -x, - x, + 2x, + Zx, + x, + lOx, + 3x, = 14 15x, + 16x2 + 1 lx, + IOx, + lOx, + 18x6- x, = 11 12x, + llx, -t 18x4+ I~x,+ 1Ox,= 17 13x, - x, +5 x, + 2x, + 9x, + 16x, = 8 4x, + 12x2 - 2x3 + x, + 3x, + 2x7 = 14 lable F 12 The half-space range search time (milliseconds) when dimension k = 7, size n = 105 5equation of the hyper plane #pts found iearch time 18x, i13x, + 7x, + 3x4+ 13x, + 4x6 +5x, = 5 -x, +x, +7x3+ ~~X~+X~+~X~+X,=17 13x, + 9x2 + 6x3 + 1lx, + x, + 18x7= 9 12x,+ 5x2 +6x, +5x,+ 16x,+3x,+x7= 17 l(lxI + 13x2 + 13x4+ 6xs + lOx, + 15x7= 3 1tix, + 15x, + 15x3+ lox, + 15x5+13x, +12x, = 2 2,Cl + 12x3 + 7x4+ 17x5+ 5x6+ I5xl=O 1! jx, + 16x, + 12x3+ 12x4+ 6x, - x, = 8 41cl+ 14x1 +8x3+12x4+7x5+ 17x6+ 14x7=9 3 Jr, + lOx, + 17x3- x, + 16x, + 4x, + 9x1= 6 9: K, + 16x2 + 12x3 + 5x5+ lOx, + 16x7= O 1:2x1 + 2x2 + 15x3 + 13~~+ 13x5 - X6 = O 5:xI + 13x, -x,+9x4+x5+ 10x,+6x7=9 4:XI + 2x2 + 15x3 + 12x4+ 12x5 - X, + 12x1 = 14 11x1 + 2x2 +4x3 + X~ + x5 + 9x6 + 8x1 =O 7 x, -x2 + 13x3+9x,+ llx, + 17x6+ 3x7= 18 -1 + 1lx2 + 14x3 + 18x6=0 1OxI+2x2 f 14x3+ 11~~+11~~-~~~17x7= 1 7X, + 6x2 + 4x, + 3x4f x5 + 12~~+ 13x1= -1 4 x, + 13x, + 8x3 - 2x4 + lox, + 14x7= 10 1lx, + 13~:- ZX, + 7x4+ 1 lx6t- 10x7 = 18 12x, + x, + 18x3+ 16x4+ 9x, + 9x6+ 5x, = 9 2!x, + 6x2 + 16x3 + X, + 18x5 + 5x6= 11 91x1 + 6x2 + 5x3 + Ilx, +7 X, + 16x6+ I~x,= 18 1,Ox, + 15x2 + 4x3 + 16xS+ 14~~+ 13x7= 10 1.6x, + 7x2 + 13x3+ 3x4+ 3x5 - x, + 8x7 = 17 5Px, + 18x2 + 17x3 + 12x5+ Iox, + 13x, = 5 fIx, + 1lx, + 18x, + 14xh - x7= 10 1Cl + ~OX,+ 15x3 + 14~~+ 9xS+ 5x6+ 4x7 = -1 1I~x, t- X, + 15x4+ 17x5+ 7xb- x,= 16 18x, -x, + 18x,+3xs + 15x7= 6 16x, +2x2 t 13x, + 16x4+ 13xs+ x3,= 11 .x, + 12~~+ IIx3+ IIx~+x~+~x~+ ISxl=9 -xI + 6~~ + 7x3 + 8x.4 + 7x5+ 1 lxh+ 9x7 = O 17xI - X3 + 14~~+ 9x6 + 14x1 = 4 5xI + 1lx2 + 14x3 + 15x4 - 2x5 + 14xh+ 8~,=4 8x, + 1lxz + 15x3 + 2x4+ 3x, + 18x, + 13x7= 3 2x, + 8x2 + 4x4 + 14x, + 15x6- x7= 13 -2xl + 4x, -i9x3 + 1 lx, + 2x5-+ xh f 14x7= 10 12~,+ 16~~+ I~x,+ 7x4 + 1 lx5+ 14xh= -1 SX, + 5x2 + 17x3 + 3x4+ 5xh + 5~,=8 7x, + 5x2 + 18x3+ 12x4+ 5x, + 8x, +9x, = 6 1lx, + x, + IOx, + 15x5+ 2x, + 16x7= 6 -2x, + 3x2 -+ f2x, + 14x, - x, + 12x, - x, = -1 9x, -+ 8x, + 10x, + 7x5+ 8x, + 15x7 = O xl + 12x2 + 12x, -t lOx, + 14x, + 15x, = 10 14x, + 7x2 + 12x3+ l6x, -2x, + 16x, +3 X, = 18 L The half-space range search time (milliseconds) when dimension k = 1 O, size n = 1 O4 - I equation of the hyper plane fpts found iearch time iodes % 17xl+13x1+9x,+17x4+14xs+9x7+lox,+10x9-xlo=lo The half-space range search time (milliseconds) when dimension k = 10. size n = 1 Q4 I I 1 equation of the hyper plane 1 #pts found st iodes % 1.4% 53.9% 100% 100% 100% 53.9% 100% 0.3% 0% The half-space range search time (nilliseconds) when dimension k = 10, size n = 5* lQ4 I 1 I equation of the hyper plane #pts found search time riodes %

3x,+ 14x,+5x3+16x4+ g~~+5~~+8~~+12xR+16x9+9xl0=4 5x1+ 13x2+6x3+3x4+1 5~~8~fi3~7~~o~~+5~~+7~~~=9 1 lx,+l 1x2+12x3+4x,+5x,+5x,-x,+3x9+l 7xlO=l1 18x,+9x1+6x,+8x4+9x,+1 7x7-2xR+4x9+ 15xl,,=5 dimension k= IO, size n= W04 #pts found :arch time nodes % F55.5% The half-space range search time (milliseconds rhen dimension k = 10. size n = 1Os 1 equation of the hyper plane ipts found 1 search time The half-space range search time (rnilIiseconds) when dimension k = 10, size n = 1Os 1 I l equation of the hyper plane L#tPtsfound wch time Appendix G Average Search Time for Half-Space Range Search The average half-space range search time (milliseconds) for the k-d Search Skip List % of points in range 10% or less 40 to 60% 90% or more ( # points 1 Average search time in milliseconds I Appendix H Complete Source Code for the Test D& Routines for the k-d Search Skip List and the Half-Space Range Search testhss: kdtesths.0 hskdlist.0 CC -O $@, kdtesths-Ohskd1ist.o -lm HZ The Füe bbkdskiplist.h"

// File name: kdskiplist-h 11 Description: Deciarations of class templates 11 KDSS kipNode // KDSSkipList // Written by: Yunlan Pan // Date: April 1 7, 1997 // // Detaiis: KDSSkipListcP: implements a k-d search skip list // that has the following rnethods: // - insert data // - delete data // - semi-infinity range search // - range search // - search a node for data Il - traverse entire list // //**********************************************************************

#define k 5 // Suppose our dimension is 10 #define maxht 64 // for deietion stack #define rnin(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b)) // Replace maxkey and minkey by the max and min of T (the template) #define maxkey 2 147483647 // rnaxkey := (2"3 1)-1 #define minkey -2 147483648 // minkey = -(2"3 1) - 1

template class KDSSkipList: // predeclaration //********************************************************************** // class KDSSkipNode // T: non pointer! e.g, int, float, object of string class. etc. // Such class T must have copy constructor, overloaded assignment // operator and overioaded operators: ==, >, <, etc. //**********************************************************************

temp1ate-X lass T> class KDSSkipNode t friend class KDSSkipList; ., . KDSSkipNode(const T inKeys[k], const char* inName); -KDSS kipNode();

void setName(const char* name); void setData(const T val[k]); void setMin(const T min1 [k]); void setMin(const T rninl[k], const T min2[k]); void setMax(const T maxl [k]); void setMax(const T maxl [k], const T max2[k]); int isMinLeqInput(const T input[k]) const; int isMaxGeqInput(const T input[k]) const; int isDataInRange(const T* minR, const T* maxR) const; int isDataInRange(const T* min& const T& highl) const; int isDataInRange(c0nst T& low 1, const T* rnaxR) const:

****************************************************************** class KDSSkipList // Assurnption: different nodes have different first key, i.e. key[O]. //********************************************************************** template4ass P class KDSSkigList { //******a****************** PUBLIC mRFACE************************* public: KDSSkipList(); -KDSSkipList(){cIear(); }

const ICDSSkipNode* getHead() const { retum head: 1 int getHeight() const; int insert(const T val[k], char* narne=NULL); const KDSSkipNode* search(const T& val. long& nurnOfCornps) const; void rangeSearch(const KDSSkipNode& startNode, const T minRange[k], const T maxRange[k], const T& rnaxfirst, long& numFound) const: void rangeSearchUp(const KDSSkipNode& startNode. const T minRangeEk], const T& high 1. 11 max range for x-1 const T& maxFirst. long& numFound) const; 11 up semi-infinite vola rangebearcN)own(const KDSS kipNode& startNode, const T mauRange[kj, const T& lowl, // min range for x-l const T& maxFirst, long& numFound) const; // down semi-infinite int deleteNode(const T& v); void prinList() const; private: KDSSkipNode *head, *bottom, *tail;

void newMaxMin(KDSSkipNode& inNode); // reset the rnax and min for // x-2, ..., x-k void printNodeData(const KDSSkipNode& node) const; void pnntNodeMin(const KDSSkipNode& node) const; void printNodeMax(const KDSSkipNode& node) const; void clear(); 1; u********************************************************************** // Module: kdskiplist.cc // Description: Implementation of KDSSkipNode and KDSSkipList classes // Written by: Yunlan Pan // Date: May 17, 1997 // //**********************************************************************

// Description: Default constructor of KDSSkipNode. //********************************************************************* template KDSSkipNode: :KDSSkipNode() : right(NULL), down(NULL), name(NULL)//, seq(0) i // Do useless initialization for (int i=O; ick; i*)

keys[O][i]=O; keys[l][i]=O; keys[2][i]=O; 1

II - ...... // Description: Constructor of KDSSkipNode. //********************************************************************* templatecciass T> KDSSkipNode::KDSSkipNode(constT inKeys[k], const char* inName) : right(NULL), down(NULL), name(NULL)//,seq(0) i

//********************************************************************* l/ Description: Destructor of KDSSkipNode...... KDSSkipNode::-KDSSkipNode()

if (name != NULL) delete[] narne;

// Description: Set the name of the node. //********************************************************************** template void KDSSkipNodename) { detete[] name; this->name = NULL; t

// Set the new name if (inName != NULL) { name = new char[strlen(inName)+ 11; strcpy(name, inName); 1 1

// Description: Set the k key values and the name for the node. //********************************************************************* template void KDSS kipNode: :setData(const T inKey s[k]) { for (int +O; ick; i++) { keys[O][i] = inKeys[i];

// Description: Set the minimum values of x-2, ..., x-k as the minimum // of minl[i] and min2[i]...... template void KDSSkipNode

for (int i= 1; ick; i++) t // Description: Set the minimum values of x-2. ..., x-k as the input //********************************************************************* ternplate void KDSSkipNodecT>::setMin(const T minO[k]) f for (int i=l: ick; i++)

// Description: Set the maximum values of x-2, ..., x-k as the maximum // of max I [il and max2[i].

ternplatecclass ï=- void KDSSkipNodec'I'>::setMax(const T maxl [k], const T max2[k]) { for (int i= 1; i

//Description: Set the maximum values of x-2, ..., x-k as the input. //********************************************************************* template::setMax(const T maxO[kj) t for (int i= 1 ; ick; i++) { keys[2] [il = maxO[i]; 1

// Description: Check whether ail the mins are less than or equal to the // input. Returns 1 if true, O otherwise. //********************************************************************* template int KDSSkipNode::isMinLeqInput(constT input[k]) const { 11 w e nave only K- i minimums for (int i=l; i&; i*) { if (keys[l][i] > input[i]) return O; 1

return 1; }

// Description: Check whether al1 the maxs are greater than or equal to the // input. Retums 1 if true, O otherwise. //********************************************************************* templatecclass T> int KDSSkipNode::isMaxGeqInput(const T input[k]) const { // We have only k-1 maximums for (int i= 1 ;ick; itt-)

if (keys[2][i] < input[i]) retum O; 1

// Description: Check whether al1 the data are inside the given range. // If minR == NüLL, then we check whether ail the data do II not exceed maxR; If maxR == NULL, check ail the data // not less then mi&. True, retums 1, false, returns O. // minR and maxR are amys with k elements. //********************************************************************* template int KDSSkipNode

Il We have k values to check if (rninR == NULL)

for (i=O; ick; i++) if (keys[O][i] > maxR[i]) retum O; 1 else if (rnaxR == NULL) t for (i=O; ick: i++) if (keys[O][i] c rninR[ij) remm u; 3. else t for (i=O; i maxR[i])) return O; 1

retum 1; 1

//********************************************************************* // Method: isDataInRange() // Description: Check whether al1 the data are inside the given range. // ([minR[O], highl], [minR[l], infinity), ... // //*********************************************************************[minR[k- 11, infinity) } . T'tue, retums 1, fafse, returns O. template4ass T> int KDSSkipNode::isDataInRange(const T* minR const T& highl) const i // We have k values to check if (keys[O][O] > highl) return 0; else { for (int i=O; i

retum 1; !

// Method: isDataInRange() // Description: Check whether al1 the data are inside the given range. // {[lowl, rnaxR[O]], (-infinity, maxR[l]], ... // (-infinity, maxR[k- 111 1. True. retums 1, false, retums O. //********************************************************************* template int KDSSkipNode::isDataInRange(const T& Iow 1. const T* maxR) const { 11 We have k values to check if (keys[O][O] < low 1) return O; for (int i=O; i rnaxR[i]) retum O; I

retum 1; t

//********************************************************************* // Description: Constmctor of KDSSkipListcT>. //*********4***************3****4****************************4****4******* template KDSSkipList::KDSSkipList() { int i=0;

head = new KDSSkipNode(); tail = new KDSSkipNode(); bottom = new KDSSkipNode

head->keys[O] [O] = maxkey ; for (i= 1; ikeys[ l][i] = maxkey ; head->keys[2][i] = minkey; 1 head->down = bottom; head->right = tail;

bottom->right = bottom; bottom->down = bottom;

tail->keys[O][O] = maxkey; taibright = tail; // sequence = 0; 1

//********************************************************************* // Description: retums the height of this k-d search skip list. // head and bottorn are not contributed to height. //********************************************************************* ternplatecclass T> int KDSSkipList::getHeight()const t KDSS kipNode* x = head->down; h = 0; while (x !=bottom) { x = x->down; h*; 1 return(h); i

// Description: Retums the node whose keys[0][0] matches the input. // If there is no node matching it, bottom node will // be returned. //********************************************************************* templatecclass T> const KDSSkipNode<'i,* KDSSkipList::search( const T& val, long& numOfComps) const { KDSSkipNode* tmpNode: numOfComps = 0;

tmpNode = head; while (tmpNode != bottom)

while (val > tmpNode->keys[O][Oj) { tmpNode = tmpNode->right; numOfComps++; 1

if (tmpNode->down == bottom) I numOfComps++; retum( (val == trnpNode->keys[O][O]) ? tmpNode : bottom ); 1 tmpNode = tmpNode->down; i

return bottom; !

//********************************************************************* // Description: Insert the data val[k] and name into the // k-d search skiplist. If the data is already in // the list, it retums 0, otherwise it retums 1, // which means that the data was inserted successfully. template int KDSSkipListcT>::insert(const T val[k], char* name)

KDSSkipNodecT>* tmpNode = head; KDSSkipNode

register int inSub = 0; // 1 if val[O][O] goes in tmpNode's subtree. register int addl = 0; 11 1 if a node was added at this level. register int success = 1;

// Set the bottom just for the compansorn consistency bottom->setData(val); bottorn->setName(name): bottom->setMin(val); bottorn->setMax(vai);

// Do at each level while (tmpNode != bottom)

// find where you drop while (*val > tmpNode->keys[O][O]) tmpNode = tmpNode->right;

add 1 = 0; if (tmpNade->keys[O][O] > tmpNode->down->right->right->keys[O][O]) -i // if 3 elms at level below, or ... // ... at bottom level + must insert.., // ... ==> raise rniddle elm // Add a node. Include keeping track of minimum // and maximum y as the node is added. newNode = new KDSSkipNodecP; // sequence t+; newNode->right = tmpNode->right; newNode->down = tmpNode->down->right->right; tmpNode->right = newNode; inSub = (tmpNode->down->right->keys[O][O]> *val); newNode->setData(tmpNode->keys[O]); newNode->setName(tmpNode->name); newNode->setMin(newNode->down->keys[Il, newNode-Bdown->right->keys[11); newNode->setMax(newNode->down->keys[2j, newNode->down->right->keys[2]);

if (!inSub) \ newNode->setMin(newNode->keys[l], val); newNode->setMax(newNode->keys[2],val): !

if (newNode->down == bottom) ..- .. ..uuv - aruvriir\~~s~p~iwUG-~hGy3L 1 J J, newNode->setMax(tmpNode->keys[2]); newNode->setName(tmpNode->name);

tmpNode->setData(tmpNode->down->right->keysE01); tmpNode->setName(tmpNode->down->right->name); tmpNode->setMin(tmpNode->down->right->keys[13, tmpNode->down->keys[ 11); tmpNode->setMax(tmpNode->down->right->keys[2], tmpNode->down->key SM); if (inSub) i tmpNode->setMin(tmpNode->keys[1],val); trnpNode->setMax(tmpNode->keys[2], val);

addl = 1; 1 else if (trnpNode->down == bottom) // if insert-Key already in KDSkipList success = 0;

if(trnpNode->down != bottom && !add 1) i tmpNode->setMin(tmpNode->keys[l], val); tmpNode->setMax(tmpNode->keys[2], val); 1 tmpNode = tmpNode->down; //while

if (head->right != tai 1) \ // raise height of KDSSkiplist if necessary newNode = new KDSSkipNodedown = head: newNode->right = tail: newNode->keys[O][O] = maxkey; //sequence ++; //newNode->seq = sequence: newNode->setMin(newNode->down->keys[11, newNode->down->right->keysf 11); newNode->setMax(newNode->down->keys[2], newNode->down->right->keys[2]); head = newNode; 1

//********************************************************************* // Description: Perform range search on k-d prionty search tree // al1 points lying inside the range ([rninl :maxl], // [min2:max2], ..., [mink:maxk]). // Argument: // maxFirst: maximum first dimensional value in the subtree // rooted starNode. //********************************************************************* template void KDSSkipList::rangeSearch(const KDSSkipNode& startNode, const T minRange[k], const T maxRange[k], const T& maxFirst, long& numFound) const

if ((&starNode != bottom) && (&startNode != tail)) i if ((startNode.down != bottom) && (startNode.isMinLeqInput(maxRange)) Br& (startNode.isMaxGeqInput(minRange))) // Not leaf level // Check the first data to see which branch it goes if (*minRange <= startNode.keys[O]fO]) rangesearchf *startNode.down, minRange, maxRange, startNode.keys[O][O], nudound); if ((startNode. keys[O] [O] < *maxRange) && (startNode.keys[O] [O] < maxFirst)) mngeSearch(*startNode.right, minRange, rnaxhnge, rnaxFirst, numFound); 1 else if (startNode.down == bottom) { // leaf level, report points if in range if (startNode.isDataInRange(minRange, maxRange))

//printNodeData(startNode); numFound++; t

// Keep check the right points if ( (startNode.keys[O][O] < *maxRange) && (startNode.keys[O] [O] < rnaxFirst) ) rangeSearch(*startNode.right. minRange, maxRange. maxFirst, nudound); 1

//********************************************************************* // Method: rangesearc hUp() // Description: Perform up semi-infinite range search on k-d priority search 11 tree constnicted using a deterministic skip list. i.e., // report al1 points lying inside the range ([minl:rnaxl], // rnaxFirst: maximum first dimensional value in the subtree // rooted startNode. // high 1 : rnax range for x-1 . //********************************************************************* template::rangeSearchUp(const KDSSkipNode& startNode, const T minRange[k], const T& highl, const T& maxfirst, long& nurnFound) const

if ((&startNode != bottom) && (&startNode != tail)) { if ((startNode.down != bottom) && (startNode.isMaxGeqInput(minRange))) { // Not leaf level // Check the first data to see which branch it goes if (*minRange <= startNode.keys[O][O]) rangeSearchUp(*startNode.down, minRange, high 1, startNode.keys[O][O], numFound); if ((startNode.keys[O][O] < highl) && (startNode.key s[O][O'] c maxF irst)) rangeSearchUp(*startNode.right, minRange, high 1, rnaxFirst, numfound); 1 else if (stattNode.down == bottom) // leaf level, report points if in range if (startNode.isDataInRange(rninRange, highl)) 1 //printNodeData(startNode); numFoundU; 1

// Keep check the right points if ( (startNode.keys[O][O] < highl) && (stanNode.key s[O][Oj < maxfirst) ) rangeSearchUp(*startNode.right, minRange, high 1, maxFirst, nudound); }

// Method: rangeSearchDown() // Description: Perform up semi-infinite range search on k-d priority search // tree constructed using a deterministic skip list. Le.. // report al1 points lying inside the range ([min 1:max 11, // (-infinity, max21, ..., (-infinity, maxkj). // Argument: II rooted startNode. // highl : min range for x-1. //********************************************************************* ternpIate void KDSS kipList& startNode, const T maxRange[k], const T& low 1, const T& maxfirst, long& numFound) const { if ((&startNode != bottom) && (&starNode != tail)) i if ((startNode.down != bottom) && (startNode.isMinLeqInput(maxRange))) t // Not leaf level 11 Check the first data to see which branch it goes if (low I <= startNode.keys[O][O]) rangeSearchDown(*startNode.down, rnaxRange, low 1, startNode.keys[O][O], nurnFound); if ((startNode.keys[O][O] < *maxRange) && (startNode.keys[O][O] < maxFirst)) rangeSearchDown(*startNode.right, rnaxRange, Iow 1, maxFicst, nudound); 1 else if (startNode.down == bottom) { // leaf level, report points if in range if (startNode.isDataInRange(low 1, maxRange)) { //printNodeData(startNode); numFound++; 1

11 Keep check the right points if ( (startNode.keys[O][O] < *maxRange) && (startNode.keys[O] [O] < rnaxFirst) ) rangeSearchDown(*startNode.right, maxhnge, low 1, rnaxFirst, numFound); 1 1

//********************************************************************* 11 Method: printNodeData() // Description: Print the node (without the minimum and maximum).

template~classT> void KDSSkipListcT>::printNodeData(constKDSSkipNode& node) const { tout << endl; cout "\t Data of the Node: (": for (int i=O; i

if (node.name) cout << ", " << node.name;

// Method: printNodeMin0 // Description: Print the node's minimum values. //********************************************************************* templatecclass T> void KDSSkipList::printNodeMin(const KDSSkipNode& node) const t cout cc "\t Min of the Node: ("; for (int i= 1 ;ick- 1; itt) cout

// Method: printNodeMax() // Description: Print the node's maximum values. //********************************************************************* template::printNodeMax(const KDSSkipNode& node) const f cout "\t Max of the Node: ("; for (int i= 1; i

// Method: newMaxMin() // Description: reset the max and min for x-2, ..., x-k for inNode. // The method is called in the deletion method. //********************************************************************* template void KDSSkipList&inNode) { KDSS kipNode* tmp; int repeat; int i=O; //loop index

trnp = inNode.down; if (tmp != bottom) { L A,, in~ode.set~ax(t&>ke~s[2]); while ((tmp->keys[O][O] <= i nNode.keys[O][O]) && repeat) 1 if (tmp->keys[0][0] == rnaxkey) repeat = 0; // Update mins and maxs for inNode for (i=l; ikeys[ 1 ][il < inNode.keys[ l][i]) inNode.keys[l][i] = tmp->keys[l][il; if (tmp->keys[2][i] > inNode.keys[2][i]) inNode.keys[2][i] = tmp->keys[S][i]; 1

trnp = tmp->right; 1 1 1

// Method: deleteNode0 // Description: delete a node rnatching the input key. 11 If the deletion succeeds, it retums 1. Otherwise if there // is no such node in the list, it retums 0. 11 Implemetation notes: // If drop in last gap mergehon-ow withifrom previous gap // Second pass (always): -- after you reach bottom level // -- €rom top of DSL //********************************************************************* template int KDSSkipList::deleteNode(const T& v) 1 KDSSkipNode *x, *PX,*nx, *t, *pla[maxht]; // px: previous x // nx: next x // pla: stack int success, botlast. npla; char* predname; // name of predecessor del-key at bottom level T pred[k]; // data of predecessor del-key at bottom level T IastAbove; // righmost key on search path at level above

x = head->down; // x = current ehin search path success = (x != bottom); bottom->keys[O][O] = v; IastAbove = head->keys[O][O]; // righmost keys on search path // at level above npla = 0: pla[npla] = head: while (x != bottom) { // do at every level { II Tina wnere you drop px = x; // keeping track of the previous gap x = x->right; Z nx = x->down; // mark where to drop at level below if (x->keys[O][O] == nx->right->key s[O][O]) { // if (only 1 elm in gap ta drop) or // (at bottom level + must delete ) if (x->keys[O][O]!= tastAbove) ( // if DOESWT drop in last gap t = x->right; if ((t->keys[O](O] == t->down-pright->keys[O][O]) I i (nx == bottom) ) t // if only 1 elm in next gap or at // bottom ievel // lower separator of current+next gap x->right = t->right; x->setData(t->keys[O]); x->setMin(t->keys[ 11); x->setMax(t->keys[23); x->setName(t->name); delete t;

else f // if >=2 elms in next gap // mise 1st elm in next gap x->setData(t->down->keys[O]); // lower separator of currenttnext gap t-~down= t->down->right; newMaxMin(*t); \ t else // if DOES drop in last gap if (px->keys[O][O] <= px->down->right->keys[O][O]) { // if only 1 elrn in previous gap botlast = 0; if (nx == bottom) { // if del-Key is in elm of height>l botlast = 1 ; // predecessor of del-key at bottom level for(int j=O; jck; j++) predlj] = px->keys[O]ljf; predname = px->name; 1 // lower separator of previous+current gap r" - n-yaLAJl~ px->setMax(x->keys[2]); px->setName(x-mame); 1 delete x; x = px;

// if >=2 elms in previous gap II t = last elm in previous gap KDSSkipNode* tmp = px->down->right->right; t = (px->keys[O] [O1 == tmp-Hceys[O] [O] ? px->down->right : tmp); // raise last elm in previous gap & lower Ilseparator of previous-tcurrent gap px->setData(t->keys[O]); x->down = t-Bright; newMaxMin(*px); 1 } // end of if else if (nx == bottom) li if del-Key not in KDSSL success = 0;

lastAbove = x->keys[O][O]; npla++; pla[npla] = x; x = nx; ) // end of while

// Do a 2nd pass, for the case that del-key was in elm of heightr 1 x = head->down; while (x != bottom)

while (v > x->keys[O][O]) x = x->right;

// Check and reset mins and maxs for al1 nodes for (int i=npla; +=O; i--) newMaxMin(*pla[i]); '!on path to deleted key.

if (head->down->right == tail) ( // lower header of DSL, if necessary x = head; head = x->down; // Method: printList() // Description: Print the whole skiplist (head is printed, bottom and tail 11 are not printed. //********************************************************************* template void KDSSkipList::printList() const { KDSSkipNode *xx, *x;

cout " The List Contains the Foliowing Points:\n" << endl;

xx = head; while (xx!= bottom) t x = xx; while (x->keys[O][O] != rnaxkey)

printNodeData(*x); printNodeMin(*x); printNodeMax(*x); x = x->right; 1 cout endl; cout «"MaxKey :" << x->keys[O][O] << endl; printNodeMin(*x); printNodeMax(*x);

// Method: cleatf) // Description: Clear the whole kt. AH the memory allocated will be // released. It is used in the destructor. //********************************************************************* template void KDSSkipList::clear() { KDSSkipNode *x, *trnp, *down;

x = head; while (x != bottorn) { down = x->down; 11 hold down since xx will be deleted .. viruii biiu .CVLI wllblb A ilGJ while (x->keys[O ][O] != maxkey) { tmp = x; x = x->right; delete trnp; t delete x; // delet the node with rnaxKey

// Startç the next levei x = down; }

delete bottom; delete tail; I //********************************************************************** // File name: hskd1ist.h // Description: Declarations of class templates // KDSSkipNode // KDSSkipList // Written by: Yunlan Pan //Date: June 29, 1997, Modified the node such that it // contains the minimum and maximum values for the // first dimension too. Such modification will be used Il by the added half-space range search. // // Details: KDSSkipList: implements a k-d search skip list // that has the following rnethods: // - insert data // - delete data // - semi-infinity range search // - range search // - half-space range search (Added June 29.97) // - search a node for data // - traverse entire list ////*********************************************************************

#define k 7 // The given dimension #define maxht 64 // for deletion stack #define min(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b)) // Replace maxkey and minkey by the max and min of T (the template) #define rnaxkey 2147483647 // maxkey := (P31)-1 #define minkey -2147483648 // minkey = -(2^31) - 1

template class KDSSkipList; Il predeclaration

Il--.-.-... - // class KDSSkipNode // T: non pointer! e.g, int. float, object of string class, etc. // Such class T must have copy constnictor, overloaded assignrnent // operator and overloaded operators: ==, >, <, etc. // // Midification on June 29. 97: For half-space range search, only template class KDSSkipNode

friend class KDSSkipList;

void setName(const char* name): void setData(const T val[k]); void seMin(const T min 1[k]); void setMin(const T min1 [k], const T min2[k]); void setMax(const T max l [k]); void setMax(const T rnax 1 [k], const T max2[k]); int isDataInHalf p(const T* halfSp) const; void getLimits(const T* halfSp, double low[k], double up[k]) const; void checkPosition(const T* halfSp. const double* low, const double* up, int& in. int& prune) const; );

//********************************************************************* // class KDSSkipList // Assurnption: different nodes have different first key, i.e. key[O].

template4ass T> class KDSSkipList { ...... PUBLIC MENACE ************************** public: KDSSkipList(); -KDSSkipList() {clear();

const KDSSkipNode* getHead() const {return head; f int getHeight() const; int insert(const T val[k], char* name=NULL); void halfSpSearch(const KDSSkipNode& stanNode, const T halRp[k+ 11, const T& maxfirst, int delete~ode(constT& v); void pnntList() const;

void newMaxMin(KDSSkipNode& inNode); // reset the rnax and min for // x-2, ..., x-k void printNodeData(const KDSSkipNode4Xk node) const; void printNodeMin(const KDSSkipNode& node) const; void printNodeMax(const KDSSkipNode& node) const: void repSubList(const KDSSkipNode& bNode, long& numReport) const; void clear(); 1; II - ...... - . // Module: hskdl ist-cc JI Description: Implementation of KDSSkipNode and KDSSkipList classes // Written by: Yunlan Pan 11 Date: June 29. 1997, Modified the node such that it // contains the minimum and maximum values for the Il first dimension too. Such modification will be used // by the added half-space range search. // //*********************************************************************

Il Description: Default consmictor of KDSSkipNode. //********************+************************************************** template KDSSkipNode::KDSSkipNode() : right(NULL), down(NULL), narne(NULL)//, seq(0) { 11 Do useless initialization for (int i=O; ick; i++) { keys[O] [i]=O; keys[ 1][i]=0; keys[2][i]=0;

//********************************************************************* // Description: Constnictor of KDSSkipNode.

ternplate KDSSkipNode::KDSSkipNode(constT inKeys[k], const cha? inName) : right(NULL), downWL), name(NULL)//, seq(0) // Description: Destnictor of KDSSkipNode.

template KDSSkipNode<'l,::-KDSSkipNode() { if (narne != NULL) delete[] name;

// Description: Set the name of the node. //********************************************************************* template::setName(const char* inName) { // Clear old name first if (this->name)

delete[] narne; this->name = NLTLL; 1

// Set the new name if (inName != NLJLL) f name = new char[strlen(inName)+ Il; strcpy(name. inName); 1

//********************************************************************* // Description: Set the k key values and the name for the node.

template void KDSSkipNode::setData(const T inKeys[k]) { for (int i-O; i

// Description: Set the minimum values of x-1, .... x-k as the minimum // of min 1[il and min2[i]. //********************************************************************* // Description: Set the minimum values of x-1, ..., x-k as the input ...... tempIate void KDSSkipNode::setMin(const T minO[k])

for (int i=O; i

keys[l][i] = rninO[i]; t I

// Description: Set the maximum values of x-1, ..., x-k as the maximum // of max 1 [il and max2[i]. //********************************************************************* ternplate

// Description: Set the maximum values of x-1, ..., x-k as the input. //********************************************************************* template void KDSSkipNode::setMax(const T maxO[k]) 1 for (int i=O; i

//********************************************************************* 11 Method: isDataInHalfSp() // Description: Used only by half-space range search. II or tne input hyperplane. Rehirn 1 if it is, O otherwise. // For the node previous tail in the leaf level. it returns O. //*********************************************************************** ternplate int KDSSkipNode~T~::isDataInHalfSp(constT* halfcip) const { if (keys[O][O] -= maxkey) i // No data in such node, like head retum O; Z

T lside = 0; for (int i=0; i

if (Iside > half!Sp[k]) return 1 ;

retum 0;

// Method: getLimits() // Description: This method is used by half-space range search. // Get the lower and upper Iimits to help determine whether // we should report a subtree or prune a subtree. // Arguments: // halfSp: input, k+l array of coefficients of the hyperplane. // low: output, x'-i in the thesis. // up: output, x"_i in the thesis. //********************************************************************* template void KDSSkipNode::getLimits(const T* halfSp. double low[k], double up[k]) const { T mins[k], maxs[k]; int i; // Loop index

for (i=O; i 0)

mins[ij = -halfSp[i]*keys[Z][i]; maxs[i] = -halfSp[i]*keys[l )[il; i else if (halfSp[i] < 0) f mins[i] = -halfSp[i]*keys[l][i]; // Get the low and up double hrnins = rnins[O]; double hrnaxs = maxs[O]; for (i= 1 ; i

for (i=O; i

// Method: checkPosition() // Description: This method is used by half-space range search. // Check whether the subtree starts at this node completely // resides in the positive side of the hyperplane or should // be pruned or should be checked more. // Arguments: // halfSp: input, k+l anay of coefficients of the hyperplane. // low: input, x'-i in the thesis. // up: input, x"-i in the thesis. // in: output, 1 means the subtree raides in the half-space. Il prune: output, O means the subtree should not be pruned. //********************************************************************* template void KDSSkipNode::checkPoçition(const T* halfSp, const doubte* low, const double* up, int& in, int& prune) const { // Initialize the outputs in = prune = 0; if (((halfSp[i] > 0) && (keys[S][i] < low[ij)) 1) ((halfSp[i] < O) && (keysr l][i] > up[i])))

prune = 1; // The subtree should be pruned. retum; f eise if (((halfSp[i] > 0) && (keys[l][ij > up[i])) [I ((haIfSp[i] < 0) && (keys[2][i] c low[i])))

in = 1; // The subtree resides in the halp-space. retum; 1 1

//********************************************************************* // Description: Constmctor of KDSSkipList. //********************************************************************* template KDSSkipList::KDSSkipList()

int i=O;

head = new KDSSkipNodecT>(); tail = new KDSSkipNode(); bottom = new KDSSkipNodecP();

head->keys[O][O] = maxkey; for (i=0; ikeys[l][i] = maxkey; head->keys[2][il = minkey; I f head->down = bottom;

bottorn->right = bottom; bottom->down = bottom;

tail->keys[O][O] = maxkey ; tail->right = tail; // sequence = 0; t

//*********************************************************************** // Description: returns the height of this k-d search skip list. template~classT> int KDSSkipList~T>::getHeight()const { register int h;

KDSSkipNode* x = head->down; h = 0; while (x!=bottorn)

x = x->down; h++; } return(h); 1

II ..-. -- ...---..-.....-...- // Description: Insert the data val[k] and name into the // k-d search skiplist. If the data is already in // the list, it returns O, otherwise it retums 1, // which means that the data was inserted successfully. //********************************************************************* tempiate int KDSSkipList* newNode = NULL;

register int inSub = 0; // 1 if val[O][O] goes in tmpNode's subtree. register int addl = 0; 11 1 if a node was added at this level. register int success = 1;

// Set the bottom just for the comparisom consistency bottom->setData(val); bottom->setName(name); bottom->setMin(val); bottom->setMax(val);

// Do at each level while (tmpNode != bottom) t // find where you drop while (*val > tmpNode->keys[O][O]) tmpNode = tmpNode->right;

addl = 0; if (tmpNode->keys[0][0] > tmpNode->down->right->right->keys[O][O]) t // if 3 elms at level below, or ... // ... at bottom Ievel + must insert... // Add a node. Include keeping track of minimum // and maximum y as the node is added. newNode = new KDSSkipNode; // sequence ++; newNode->right = tmpNode->right; newNode->down = tmpNode->down->right->right; trnpNode->right = newNode; inSub = (tmpNode->down->right->keys[O][O] > *val); newNode->setData(tmpNode->keys[O]); newNode->setName(tmpNode->name): newNode->setMin(newNode->down->keys[l], newNode->down->right->keys[11); newNode->setMax(newNode->down->keys[2], newNode->down->right->keys[21); //newNode->seq = sequence;

if (!inSub) { newNode->setMin(newNode->keys[l], val); newNode->setMax(newNode->keys[2], val);

if (newNode->down == bottom) 11 leaf level newNode->setMin(tmpNode->keys[ 11); newNode->setMax(tmpNode->keys[2]); newNode->setName(tmpNode->name); 1 tmpNode->setData(tmpNode->down->right->keys[O]); tmpNode->setName(tmpNode->down->right->name); tmpNode->setMin(trnpNode->down->right->keys[11, tmpNode->down->keys[ 11); tmpNode->setMax(tmpNode->down->right->keys[2], tmpNode->down-> keysv]); if (inSub) ! tmpNode->setMin(tmpNode->keys[l],val); tmpNode->setMax(tmpNode->keys[2], val);

addI = 1; 1 else if (tmpNode->down == bottom) // if insert-Key already in KDSkipList success = 0;

if(tmpNode->down != bottom && !add 1) { tmpNode->setMin(tmpNode->keys[l],val); tmpNode->setMax(tmpNode->keys[2],val): if (head->right != tail) { // raise height of KDSSkiplist if necessary newNode = new KDSSkipNodecT? newNode->down = head: newNode-Bright = tail: newNode->keys[O][O] = maxkey; Ilsequence ++; //newNode->seq = sequence; newNode->setMin(newNode->down->keys[11, newNode->down->right->keys[II); newNode->setMax(newNode->down->keys[2], newNode->down->right->keys[2]); head = newNode; 1

...... ------. . -...... ---r---.- II -- . . . . - . -.. .- // Method: halBpSearch() // Description: Perforrn half-space (positive side) search on k-d search // tree constructed using a deterministic skip list. i.e., // report al1 points lying inside the positive side of a // hyperspace. // Argument: // maxFirst: maximum first dimensional value in the subtree // rooted startNode. // halfSp: coefficients of halfplan a-lx-1 + ... + a-kx-k // = m where a-1 != 0. //********************************************************************* template void KDSSkipList::halfSpSearch(constKDSSkipNode& startNode. const T halfSp[k+l], const T& maxFirst, long& numFound) const

if ( (startNode.keys[O][O] == maxkey) && (startNode.down == bottom) ) { // Last node in the leaf ievel (the node previous tail) retum; 8 else if ( (startNode.keys[O][O] == maxkey) && (startNode-down != bottorn) && (&startNode != tail) ) t // A previous node of tail. just go down halfSpSearch(*startNode.down, halfSp. startNode.keys[Oj[Oj, numfound): else if ((&tafiNode != bottom) && (&starNode != tail)) { // Get the bounds double low[k], up [k]; startNode.getLimits(halfSp, low, up);

if (startNode.down == bottom) { // Leaf level, report points if in half space. if (startNode.isDataInfIalfSp(halfSp)) { //pnntNodeData(startNode); numFound++; 1

// Keep check the right points if (startNode.keys[O][O] < maxFirst) { if ((haISp[O] > 0) II (startNode.keys[O][O] < up[O])) halfSpSearch(*startNode.right, halfSp, maxFirst, numFound); 1 } else //startNode.down != bottom) Le. not leaf level { // Check to report or prune down. int in=O, pmne=O; startNode.checkPosition(halfSp,low, up, in, prune);

if (in) //Report the subtree this->repSubList(startNode, numFound); else if (!prune) // Check downword halfSpSearch(*startNode.down, halffp, startNode.keys[O][O], numFound);

// Check to branch the right if ( (startNode.keys[O][O] < maxFirst) && ( (halfSp[OI '0) II (startNode.keys[O][O] < up[O]) 1 ) halfSpSearch(*startNode.right, halffp, maxFirst, numFound); 1 1 i

//********************************************************************* // Method: printNodeData0 // Description: Print the node (without the minimum and maximum). template void KDSSkipListcT>::printNodeData(const KDSSkipNode& node) const

cout << endl; cout << "\t Data of the Node: ("; for (int i=O; i

if (node.name) cout ", " << node.name;

//********************************************************************* // Method: printNodeMin() // Description: Print the node's minimum values. //********************************************************************* template~classT> void KDSSkipList

tout << "\t Min of the Node: ("; for (int i=O; iek- 1; i*) cout -=< node.keys[l][i] ",";

cout << node.keys[l][k-1] «O);" << endl; I

//********************************************************************* // Method: pnntNodeMax() // Description: Print the node's maximum values. //********************************************************************* ternplatecclass T> void KDSSkipList::printNodeMax(const KDSSkipNode

// Method: newMaxMin() // Description: reset the rnax and min for x-1. ..., x-k for inNode. // The rnethod is called in the deletion method. //********************************************************************* template void KDSSkipList::newMaxMin(KDSSkipNode& inNode) int repeat; int i=O; //loop index

tmp = inNode.down; if (tmp != bottom) t repeat = 1; inNode.setMin(trnp->keys[ 11); inNode.setMax(tmp->keys[2]); while ((trnp->keys[O][O] <= inNode.keys[O][O]) && repeat) { if (tmp->keys[O][O] == maxkey) repeat = 0; // Update rnins and maxs for inNode for (i=O; ikeys[ l][ij < inNode.keys[ l ][il) inNode.keys[ l][i] = tmp->keys[l][i]; if (tmp->keys[2][i] > inNode.keys[2][i]) inNode.keys[2][i] = tmp->keys[Z][i]; !

trnp = tmp-aight; 1

// Method: deleteNode() // Description: delete a node matching the input key. 11 If the deletion succeeds, it returns 1. Otherwise if there // is no such node in the list, it retums O. // Irnplemetation notes: // If drop in last gap merge/borrow with/from previous gap // Second pass (always): -- after you reach bottorn level // -- from top of DSL //*********************************************************************** template int KDSSkipList::deleteNode(const T& v) { KDSS kipNode *x, *PX, *nx, *t, *pla[maxht]; // PX: previous x // nx: next x // pla: stack int success. botlast, npla; char* predname; // narne of predecessor del-key at bottorn level T pred[k]; // data of predecessor del-key at bottom level T IastAbove: // righmost key on search path at level above success = (x != bottom); bottom->keys[O][O] = v; IastAbove = head->keys[O][O]; // nghmost keys on search path // at level above npla = 0; pla[npla] = head; while (x != bottom) { // do at every level while (v > x->keys[O][O]) { // find where you drop px = x: // keeping track of the previous gap x = x->right;

nx = x->down; // mark where to drop at level below if (x->keys[O][O] == nx->right->keys[O][O]) { // if {only 1 elrn in gap to drop} or // {at bottom level + must delete) if (x->keys[O][O] != IastAbove) ( // if DOESN'T drop in last gap t = x->right; if ((t->keys[O][O] == t->down->right->keys[O][O]) II (nx == bottom) ) { // if only 1 elrn in next gap or at // bottom level // lower separator of current+next gap x->right = t->right; x->setData(t->keys[O]); x->setMin(t->keys[ LI); x->setMax(t->keys[2]); x->setNarne(t->name); delete t: 1. else { // if >=2 elms in next gap lI mise 1st elm in next gap x->setData(t->down->keys[O]); // lower separator of current+next gap t-7down = t->down->right; newMaxMin(*t); I. I else // if DOES drop in last gap if (px->keys[O][O] <= px->down->right->keys[O][O]) { // if only 1 elm in previous gap botlast = 0; if (nx == bottom) { // if del-Key is in elrn of height>l botlast = 1; -,------.--.---. for(int j=0;<keys[O]lj]; predname = px->name;

// lower separator of previous+current gap px->right = x->right; px->keys[O][O] = x->keys[O][O]; if (!botlast) t px->setData(x->keys[Ol); px->setMin(x->keys[l]); px->setMax(x->keys[2]); px->setName(x-hame); 1 delete x; x = px; I else { // if >=2 elms in previous gap // t = 1stelm in previous gap KDSSkipNodecT>* tmp = px->down->right->right; t = (px->keys[O][O] == tmp->keys[O][O] ? px->down->right : tmp); // mise last elm in previous gap & lower // separator of previous+current gap px->setData(t->keysp]); x->down = t->right; newMaxMin(*px); 1 ) // end of if else if (nx == bottom) // if det-Key not in KDSSL success = 0;

lastAbove = x->keys/O] [O]; npla*; pla[npIa] = x; x=nx; } // end of while

// Do a 2nd pass, for the case that del-key was in elrn of height> 1 x = head->down; while (x != bottom)

while (v > x->keys[O][O]) x = x->right; Il Check and reset mins and maxs for al! nodes for (int i=npla; +=O; i--) newMaxMin(*pla[i]); !/on path to deleted key.

if (head->down->right == tail) { // lower header of DSL, if necessary x = head; head = x->down; delete x; t

II . - - . . . . . - ...... // Method: printlist() // Description: Print the whole skiplist (head is printed. bottom and tail // are not printed. //********************************************************************* template void KDSSkipList::printList() const

cout «" The List Contains the Following Points:\n" << endl;

xx = head; while (xx!= bottom) t x = xx; while (x->keys[O] [O] != maxkey) { printNodeData(*x); printNodeMin(*x); printNodeMax(*x); x = x->right; 1 cout keys[O][O] << endl; printNodeMin(*x); printNodeMax( *x); // Description: Report ail the leave nodes contained in the sublist starts // with bNode. // Argument: // nudeport: number of nodes reported, the function does not // do initialization for it, it just add the number of nodes // reported here to its previous value. // //********************************************************************* template void KDSSkipListcT>::repSubList(const KDSSkipNodecT>& bNode, long& numfieport) const { const KDSSkipNode* temp = &bNode;

// Get to the leaf level while (temp->down != bottom) temp = ternp->down;

// Report al1 the Ieaf nodes in the sublist. while ( (temp->keysjO][O] < maxkey ) && (temp->keys[O][O] <= bNode.keys[O] [O]) )

//printNodeData(*temp); //pnntNodeMin(* temp); //printNodeMax(* temp); numiteport*; ternp = ternp->right;

// Method: clear() // Description: Clear the whole list. All the memory allocated will be // released. It is used in the destructor. //********************************************************************* template::clear() f KDSSkipNode *x, *tmp, *down;

x = head; whiIe (x != bottorn) i down = x->down; // hold down since xx will be deleted

// Clean the level where x lies while (x->keys[O][O] != maxkey) t tmp = x; x - x-2ngnt; delete tmp; \ delete x; // delet the node with maxKey

// Starts the next level x = down; 1

delete bottom; delete tail; t nb xhe File b6kdtest.cc3'

//********************************************************************* // Module: kdtest.cc // Description: Implementation of k-d search skip list // Written by: Yunian Pan // Date: April 17. 1997 // Log: June 29, 1997, Added half-space range search. // //*********************************************************************

#inchde #inchde cstdi0.b #inchde #inchde #inchde #include // library routines

#i fdef HALFSPACE #inchde "hskdlist.hl' #else #inchde "kdskip1ist.h" #endif

#define SAMPLESIZE 1OOOOL #define QWAREARATIO 0.8 #define MILLISEC-PER-SEC 1O00

void getQueryWin(long*, long*, long*, long*, long keys[SAMPLESIZE][k], float*);

main() i long startT, endT: long i, keysA[SAMPLESIZE][k]; int j; long* dataIter = NULL; // pointer iterator of the array keysA //char* names[SAMPLESIZE];

const long maxTest = 53687091 2L; //2^29

// Randomly get the sample data. for (i=OL; i

// Create an empty skiplist KDSSkipList kdlist: long unsucNum = OL; // Number of points failed to insert

// We use pointer to accelerate the access of data to the array datalter = keysA[O];

for (i=OL; icSAMPLESIZE; itt-) t // Only insert if x not already there. if (O == kdlist.insert(dataIter))

unsucNumi-+; Ilcout << "key: " << keysA[i][O]

datdter += k; 1 cout «"\fi Total " «unsucNum; cout << " nodes are already in the list" CC endl;

endT = clock(); endT = clock()/MILLISEC-PER-SEC;

cout «"Insert times in milliseconds (total " ; cout << SAMPLESIZE " nodes):" << endl; cout << "\t Total time used for insertion is " << endT-startT << endl;

long qwMinR[k], qwMaxR[k]; long wMinR[k], wMaxR[k]; float qwRatio[k]; long numFound = OL;

// Initialize the query window for (j=O; j

if (QWAREARATIO == 0) - - else qwRatiob] = (float) pow(QWAREARATIO.1 .O/k); 1 getQueryWin(qwMinR, qwMaxR wMinR, wMaxR keysA. qwhtio);

numFound = OL; kdlist.rangeSearch(*kdlist.getHead(), qwMinR, qwMaxR maxkey, nudound);

endT = clock(); endT = clock()RufDLLISEC-PER-SEC; cout "Range search times in milliseconds (total " ; cout cc numFound " nodes are found):" endl: cout "\t Total time used for this search is " endT-startT endl;

COU^ «"\n ------rangeSearchup------\dl << endl; // Calculate the query window area ratio float area = ((float)(wMaxR[O]-qwMinR[O]))/(wMaxR[O]-wMinR[O]); for (j=l; j

nudound = OL; kdlist.rangeSearchUp(*kdlist.getHead(), qwMinR, qwMaxR[O], maxkey, numFound);

endT = clock(); endT = c lock()/MILLISEC-PER-SEC;

cout cc "Semi-infinite range search (up) times in milliseconds (total " ;

Iong numFailDel = OL; // The times of deletion faiiure. // insertion failure (caused by the // duplicate keys

// We use pointer to accelerate the access of data to the amy datdter = &keysA[O][O];

for (i=OL: icSAMPLESIZE; i++) { if (kdlist.deleteNode(*dataIter) == 0) 1 //tout << keysA[i][O] " is not in the list!" endl; nurnFaiiDe1-t-t;

// Next key dataIter += k; 1 endT = clock(); endT = clock()/MILLISEC-PER-SEC;

cout "milliseconds (total " ; cout cc nuMailDe1 «" nodes are not found):" cc endl: cout CC "\t Total times (in milliseconds) used for the "; cout «"Destruction is " << endT-startT << endl; */

#ifdef HALFSPACE

COU^ << "\n------HALF-SPACE SEARCH ------\n\n" cc endi;

11 Get the hyperplane long hyplane[k+l]; struct timeval first; stmct tirnezone second: gettirneofday(&first. &second); srand48(first.tv-sec); for (i=O; i<=k; i*) hyplane[i] = (long)((lrand48() - maxTesV2 + OS)/lOOOOOOOO); // Make sure hyplane[O] != O while (hyplane[O] == 0) hyplane[O] = (long)((lrand48() - maxTesU2 + OS)/ 100000000):

// Get the hyperplane long hyplane[k+ 11;

for (i=O; i<=k; i++) { hyplane[i] = lrand480 - maxTesV2 + 0.5; 1 . -"'S., ,a.U..VLV, . V while (hypiane[O] == 0) hyplane[O] = lrand48() - maxTesti2 + 0.5;

il Pnnt the hyperplane cout "The hyperplane is: \n" c< end; for (i=O; ic=k; i++) cout << "\t" hypianeli] << " " endl; cout << end1 << endl;

long numlnHsp = OL; // The number of node in the half-space.

kdtist.halfSpSearch(*kdlist.getHead(), hyplane, maxkey, numInHsp);

endT = dock(); endT = clock()/MTLLISEC-PER-SEC;

cout «"There are (total " ; cout << numlnWsp " nodes are in the half-space):" endl; cout "\t Total times (in milliseconds) used for the " endl; cout "Half-Space range search is " endT-startT endl; #endif

//--======__=--======//Function: getQueryWin //Description: Randomly get a query window which covers a given ratio // of the area of al1 the points reside. //Argument; [qwMinR :qwMaxR] is the query window; // [wMinR : wMaxR] is the whole data window; //======---======void getQueryWin(long qwMinR[k], long qwMaxR[k], long wMinR[k], long wMaxR[k], long keys[SAMfLESiZE][k], fioat qwRatio[k]) // qwRatioCi]: the ratio of the i-th side of the query window and // its corresponding side of the whole window. { unsigned i=0, j=0; // loop index long tempMin, tempMax, temp:

// Get the whole window for (i=O; i

for (j=l;~-sAMPLESIZE: j++) t temp = Keysulli]; if (tempMin > temp) tempMin = temp; if (tempMax c temp) tempMax = temp; Z

// Get the portions randomly long wSideLen; // length of side of the whole window long qwSideLen; // length of side of the query window for (i=0; i

Q 1993. Applied tmage. Inc.. All Righis Resewed