Published online by Cambridge University Press: 05 September 2016
Throughout the book we have assumed that our compact data structures are static, that is, we build them once and they do not change anymore; we only support queries on them. In many cases the data are indeed static or change infrequently enough to allow us afford a periodic reconstruction of the data structures from scratch. In other cases, however, the data change frequently and reconstruction is unfeasible. This is the scenario we address in this chapter.
In many data types, supporting updates together with queries is intrinsically harder than the static case. For example, though we have seen that static bitvectors (Chapter 4), sequences (Chapter 6), and trees (Chapter 8) can support many operations in timeO(log log n) or less, those operations require at least time(log n/ log log n)when insertions and deletions of symbols (for bitvectors and sequences) or nodes (for trees) are allowed. In this chapter we will see practical techniques to turn those structures dynamic, with slowdown factors of typically O(w) compared to the base static representation. When n is large, O(w) becomes similar to O(log n).
Dynamism usually allows one to build the data structures within their final compressed space, by successively inserting the elements. In general, however, this construction is significantly slower than the procedures we have seen throughout the book, although the latter typically use more space.
Bitvectors
Consider a bitvector B[1, n], where in addition to the access, rank, and select operations described in Chapter 4, we support the following updates to B:
insert(B, i, b): inserts bit b between B[i − 1] and B[i], for 1 ≤ i ≤ n + 1.
delete(B, i): deletes B[i], for 1 ≤ i ≤ n.
We show how to support both the query and the update operations in time O(w) while using n + O(n/w) bits of space, where n is the size of B at the time the operation is carried out. We later consider compression.
The data structure is a classical, pointer-based, balanced search tree T (an AVL or a Red-Black tree, for example), where the leaves point to arrays of bits (these bit arrays have no further structure). Each internal node v contains two fields: v.num and v.ones are the total number of bits and of 1s, respectively, stored at the leaves that descend from the left child of v.
To save this book to your Kindle, first ensure no-reply@cambridge.org is added to your Approved Personal Document E-mail List under your Personal Document Settings on the Manage Your Content and Devices page of your Amazon account. Then enter the ‘name’ part of your Kindle email address below. Find out more about saving to your Kindle.
Note you can select to save to either the @free.kindle.com or @kindle.com variations. ‘@free.kindle.com’ emails are free but can only be saved to your device when it is connected to wi-fi. ‘@kindle.com’ emails can be delivered even when you are not connected to wi-fi, but note that service fees apply.
Find out more about the Kindle Personal Document Service.
To save content items to your account, please confirm that you agree to abide by our usage policies. If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account. Find out more about saving content to Dropbox.
To save content items to your account, please confirm that you agree to abide by our usage policies. If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account. Find out more about saving content to Google Drive.