VList

From Rosetta Code
VList is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Data Structure
This illustrates a data structure, a means of storing data within a program.

You may see other such structures in the Data Structures category.
This page uses content from Wikipedia. The original article was at VList. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)

In computer science, the VList is a persistent data structure that combines the fast indexing of arrays with the easy extension of cons-based (or singly-linked) linked lists.

Like arrays, VLists have constant-time lookup on average and are highly compact, requiring only O(log n) storage for pointers, allowing them to take advantage of locality of reference. Like singly-linked or cons-based lists, they are persistent, and elements can be added to or removed from the front in constant time. Length can also be found in O(log n) time.

The primary operations of a VList are:

  • Locate the kth element (O(1) average, O(log n) worst-case)
  • Add an element to the front of the VList (O(1) average, with an occasional allocation)
  • Obtain a new array beginning at the second element of an old array (O(1))
  • Compute the length of the list (O(log n))

Task

The task is to demonstrate creation of a VList and how to perform the primary operations.

C

<lang c>#include <stdio.h>

  1. include <stdlib.h>

typedef struct sublist{ struct sublist* next; int *buf; } sublist_t;

sublist_t* sublist_new(size_t s) { sublist_t* sub = malloc(sizeof(sublist_t) + sizeof(int) * s); sub->buf = (int*)(sub + 1); sub->next = 0; return sub; }

typedef struct vlist_t { sublist_t* head; size_t last_size, ofs; } vlist_t, *vlist;

vlist v_new() { vlist v = malloc(sizeof(vlist_t)); v->head = sublist_new(1); v->last_size = 1; v->ofs = 0; return v; }

void v_del(vlist v) { sublist_t *s; while (v->head) { s = v->head->next; free(v->head); v->head = s; } free(v); }

inline size_t v_size(vlist v) { return v->last_size * 2 - v->ofs - 2; }

int* v_addr(vlist v, size_t idx) { sublist_t *s = v->head; size_t top = v->last_size, i = idx + v->ofs;

if (i + 2 >= (top << 1)) { fprintf(stderr, "!: idx %d out of range\n", (int)idx); abort(); } while (s && i >= top) { s = s->next, i ^= top; top >>= 1; } return s->buf + i; }

inline int v_elem(vlist v, size_t idx) { return *v_addr(v, idx); }

int* v_unshift(vlist v, int x) { sublist_t* s; int *p;

if (!v->ofs) { if (!(s = sublist_new(v->last_size << 1))) { fprintf(stderr, "?: alloc failure\n"); return 0; } v->ofs = (v->last_size <<= 1); s->next = v->head; v->head = s; } *(p = v->head->buf + --v->ofs) = x; return p; }

int v_shift(vlist v) { sublist_t* s; int x;

if (v->last_size == 1 && v->ofs == 1) { fprintf(stderr, "!: empty list\n"); abort(); } x = v->head->buf[v->ofs++];

if (v->ofs == v->last_size) { v->ofs = 0; if (v->last_size > 1) { s = v->head, v->head = s->next; v->last_size >>= 1; free(s); } } return x; }

int main() { int i;

vlist v = v_new(); for (i = 0; i < 10; i++) v_unshift(v, i);

printf("size: %d\n", v_size(v)); for (i = 0; i < 10; i++) printf("v[%d] = %d\n", i, v_elem(v, i)); for (i = 0; i < 10; i++) printf("shift: %d\n", v_shift(v));

/* v_shift(v); */ /* <- boom */

v_del(v); return 0; }</lang>

C++

This example is incorrect. Please fix the code and remove this message.

Details: It only shows the declaration of the operations, not the implementation of them.

OOTL Implementation [1]

<lang cpp>template<typename T, int Factor_N=2, int Initial_N=8> struct vlist {

 public:
   typedef T value_type;
   typedef vlist self;
 protected:
   struct buffer {
       size_t index;
       size_t size_minus_one;
       size_t size;
       T* begin;
       T* end;
       buffer* prev;
       buffer* next;
   };
   struct iterator {
       typedef iterator self;
       typedef T value_type;
       iterator(buffer* x, T* y);
       iterator(const iterator& x);
       self& operator+=(size_t n);
       self operator+(size_t n);
       self& operator-=(size_t n);
       self operator-(size_t n);
       self& operator++();
       self& operator--();
       self operator++(int);
       self operator--(int);
       bool operator==(const self& x);
       bool operator!=(const self& x);
       bool operator<(const self& x);
       T& operator*();
   };
   struct reverse_iterator {
       // same as iterator
   };
 private:
   buffer* buff;
   size_t cap;
 public:
   vlist();
   ~vlist();
   buffer* get_first_buffer();
   buffer* get_last_buffer();
   T* get_pointer(size_t n);
   size_t capacity() const;
   void initialize(size_t n);
   void add_buffer();
   void add_buffer(buffer* x);
   void remove_buffer();
   void clear();
   iterator begin();
   iterator end();
   reverse_iterator rbegin();
   reverse_iterator rend();

};</lang>

References