Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data structures in lisp

I have a simple problem: to collect objects into a list and traverse this list backwards. Seems pretty easy but this code is a part of high-loaded computation. It is pretty natural to use conses because it takes O(1) on adding a new element and on sequential access. But what do i have to do if I need an effective double-linked list for traversing it easily in both directions? Use (reverse)? It takes O(n) memory and time, so actually it will take O(n^2) in my case (which is really bad). Use (last) or (append)? The same story: O(n). I do not really understand where to find (except the source code) any info on computational complexity of standard library functions. Is it implementation dependent? And what do I have to do for implementation of various standard data structures? Is there any guides on using conses effectively?

like image 584
lumberjack Avatar asked Apr 23 '11 13:04

lumberjack


People also ask

What are the data structures of Lisp?

Many applications of LISP involve storing a variety of values associated with a symbolic name. Association lists and property lists provide two ways of doing this, unique to LISP. Arrays, vectors and strings are also used for data storage and manipulation.

What are the 4 data structures?

When we think of data structures, there are generally four forms: Linear: arrays, lists. Tree: binary, heaps, space partitioning etc. Hash: distributed hash table, hash tree etc.

Does Lisp have data types?

LISP data types can be categorized as. Scalar types − for example, number types, characters, symbols etc. Data structures − for example, lists, vectors, bit-vectors, and strings.

What are the 2 main types of data structures?

Basically, data structures are divided into two categories: Linear data structure. Non-linear data structure.


2 Answers

If you use Common Lisp, you can use vectors instead. Vectors can have a fill-pointer and/or can be adjustable. So you can use vector-push to add elements to a vector. The fill-pointer will grow. If the vector is adjustable, then it will also made larger if necessary. Since vectors are one-dimensional arrays you can access the elements with an index as you like.

See the options to MAKE-ARRAY to create such a vector.

VECTOR-PUSH and VECTOR-PUSH-EXTEND are the functions to add elements.

like image 54
Rainer Joswig Avatar answered Oct 02 '22 20:10

Rainer Joswig


If you do the (reverse) once and then traverse the reversed list in sequential order, the total should just be O(2n) time (O(n) for the setup, and then another O(n) to traverse) and O(n) memory.

A doubly-linked list is not terribly complicated. As you know, a list is made of cons cells where the car points to the object than the cdr points to the next cons cell in the list.

Singly-linked list illustration

One way to do a doubly-linked list is to instead have the cdr point to another cons cell whose cdr points to the next cons cell in the list and whose car points to the previous cons cell in the list. Then you use cddr to move forward and cdar to move back.

Doubly-linked list illustration

I don't know that the standard library functions have any guaranteed complexity. Unless the specification specifies, it would be implementation-defined.

like image 31
Anomie Avatar answered Oct 03 '22 20:10

Anomie