Definition
An instance S of the parameterized data type sortseq<K,I> is a sequence of
items (seq_item). Every item contains a key from a linearly ordered data
type K, called the key type of S, and an information from a data type I,
called the information type of S. The number of items in S is called the
size of S. A sorted sequence of size zero is called empty. We use
k, i
to
denote a seq_item with key k and information i
(called the information associated with key k).
For each k in K there is at most one item
k, i
in S and if item
k1, i1
precedes item
k2, i2
in S then k1 < k2.
Sorted sequences are a very powerful data type. They can do everything that
dictionaries and priority queues can do. They also support many other operations,
in particular finger
searches and operations conc, split, merge, reverse_items,
and delete_subsequence.
The key type K must be linearly ordered. The
linear order on K may change over time subject to the condition
that the order of the elements that are currently in the
sorted sequence remains stable. More precisely,
whenever an operation (except for reverse_items) is applied to a
sorted sequence S, the keys of S must form an increasing sequence according
to the currently valid linear order on K. For operation reverse_items this
must hold after the execution of the operation. An application of sorted sequences
where
the linear order on the keys
evolves over time is the plane sweep algorithm for line segment
intersection. This algorithm sweeps an arrangement of segments by a
vertical sweep line and keeps the intersected segments in a
sorted sequence sorted
according to the y-coordinates of their intersections with the sweep line. For
intersecting segments this order depends on the position of the sweep line.
Sorted sequences support finger searches. A finger search takes an item it in a sorted sequence and a key k and searches for the key in the sorted sequence containing the item. The cost of a finger search is proportional to the logarithm of the distance of the key from the start of the search. A finger search does not need to know the sequence containing the item. We use IT to denote the sequence containing it. In a call S.finger_search(it,k) the types of S and IT must agree but S may or may not be the sequence containing it.
#include < LEDA/sortseq.h >
Types
| sortseq<K,I>::item | the item type seq_item. |
| sortseq<K,I>::key_type | the key type K. |
| sortseq<K,I>::inf_type | the information type I. |
Creation
| sortseq<K,I> | S | creates an instance S of type sortseq<K,I> based on the linear order defined by the global compare function and and initializes it to the empty sorted sequence. |
| sortseq<K,I> | S(int (*cmp) (K, K )) | creates an instance S of type sortseq<K,I> based on the linear order defined by the compare function cmp and initializes it with the empty sorted sequence. |
Operations
| void | S.merge(sortseq<K,I,seq_impl>& S1) | |
| merges the sequence S1 into sequence S and makes S1 empty.
Precondition all keys are distinct. |
||
| void | S.print(ostream& out, string s, char c=' ') | |
| prints s and all elements of S separated by c onto stream out. | ||
| void | S.print(string s, char c=' ') | |
| equivalent to S.print(cout,s,c). | ||
| bool | S == sortseq<K,I,seq_impl> S1 | |
| returns true if S agrees with S1 componentwise and false otherwise | ||
| sortseq<K,I,seq_impl>* | sortseq<K,I>::my_sortseq(seq_item it) | |
| returns a pointer to the sortseq containing it. Precondition The type of the sortseq containing it must be sortseq<K,I>. |
||
Implementation
Sorted sequences are implemented by skiplists [71]. Let n denote the current size of the sequence. Operations insert, locate, lookup and del take time O(log n), operations succ, pred, max, min_item, key, inf, insert_at and del_item take time O(1). clear takes time O(n) and reverse_items O(l ), where l is the length of the reversed subsequence. Finger_lookup(x) and finger_locate(x) take time O(log min(d, n - d )) if x is the d-th item in S. Finger_lookup_from_front(x) and finger_locate_from_front(x) take time O(log d ) if x is the d-th item in S. Finger_lookup_from_rear(x) and finger_locate_from_rear(x) take time O(log d ) if x is the n - d-th item in S. Finger_lookup(it,x) and finger_locate(it,x) take time O(log min(d, n - d )) where d is the number of items between it and the item containing x. Note that min(d,n - d) is the smaller of the distances from it to x if sequences are viewed as circularly closed. Split, delete_subsequence and conc take time O(logmin(n1, n2)) where n1 and n2 are the sizes of the results of split and delete_subsequence and the arguments of conc respectively. Merge takes time O(log((n1 + n2)/n1)) where n1 and n2 are the sizes of the two arguments. The space requirement of sorted sequences is linear in the length of the sequence (about 25.5n Bytes for a sequence of size n plus the space for the keys and the informations.).
Example
We use a sorted sequence to list all elements in a sequence of strings lying lexicographically between two given search strings.
#include <LEDA/sortseq.h>
main(){
sortseq<string,int> S;
string s1,s2;
cout << "input a sequence of strings terminated by stop\n";
while (cin >> s1 && s1 != "stop") S.insert(s1, 0);
while ( true )
{ cout << "\ninput a pair of strings\n\n";
cin >> s1 >> s2;
cout << "all strings s with " <<
s1 <<" <= s <= " << s2 <<"\n";
if ( s2 < s1 ) continue;
seq_item last = S.locate_pred(s2);
seq_item first = S.locate(s1);
if ( !first || !last || first == S.succ(last) ) continue;
seq_item it = first;
while ( true )
{ cout << "\n" << S.key(it);
if ( it == last ) break;
it = S.succ(it);
}
}
}
Further examples can be found in section Sorted Sequences of [58].
© Copyright 1995-2002, Algorithmic Solutions Software GmbH. All rights reserved.
2002-10-16