3.6. Implementation parameters

Learning objectives

Implementation parameters

The associative container types that we have got to know in this chapter represent easy-to-use interfaces for their underlying implementation. They are abstract data types that abstract from their concrete implementation. Normally, we see nothing of this implementation, and we do not want it anyway. We rely on LEDA using the optimal implementation for every type - optimal with respect to the average case of use, according to the present state of knowledge of algorithmics. But, as we said, only for the average case - there may well be special situations in which it would be of advantage to use a specific implementation of an abstract data type.

For example, the class d_array is implemented by randomized search trees by default. However, there may be situations in which the use of a skiplist would provide faster response times. Therefore some data types, primarily the associative container types and the priority queues, offer several implementations from which the experienced user can choose the one that is most suitable for his situation. But be careful! This possibility should be taken into consideration only by a user who can exhibit solid knowledge about data structures and efficient algorithms - here one should know what one does.

In this spirit, we do not want to explain here how such specialized implementations like randomized search trees or skiplists work. This would go beyond the scope of this tutorial. To understand the internal working of such structures, it is warmly recommended to read a theoretical introduction to data structures and algorithms.

Rather, we want to show by means of the example of the skiplist implementation, which can be specified as an additional implementation parameter of a d_array, how such special implementations of an abstract data type are taken advantage of in LEDA: The name of the implementation can be specified as an additional template parameter.

Here is once again a version of our program for counting strings from standard input. This version now uses a skiplist to manage the key-value pairs:

Filename: StringCountSkiplist.C
LEDA users as of version 5.0: Note that header files are now partitioned into modules (subfolders)!
#include <LEDA/d_array.h>
#include <LEDA/impl/skiplist.h>
#include <LEDA/string.h>
#include <iostream>

using leda::d_array;
using leda::skiplist;
using leda::string;

int main()
  d_array<string, int, skiplist>  counter(0);
  string s;

  while (std::cin >> s) counter[s]++;
  std::cout << "I have counted the following strings:\n";

    std::cout << s << " " << counter[s] << std::endl;

The header file of an implementation parameter to be included is always located in the subdirectory impl of the directory in which the header files of LEDA are located. The implementation parameter has to be specified as the last template argument of the type to be parameterized.

Such a specialized type like d_array<string,int,skiplist> is derived (in the sense of the language C++) from the corresponding non-parameterized type; this means here from d_array<string,int>. Therefore, the type with implementation parameter can be used in all places where the type without implementation parameter is also permitted.

A survey of the data structures that LEDA keeps ready as an implementation parameter and of the types that can be parameterized with these parameters can be found on the corresponding manual page.