cdr的时间分析

时间:2013-09-09 13:45:12

标签: lisp racket time-complexity

我无法找到cdr的时间复杂度分析。它是在恒定时间还是线性时间运行?如果答案取决于lisp的实现,假设我使用的是Racket。

3 个答案:

答案 0 :(得分:8)

cdr可以在任何Lisp中占用恒定的时间。它只是查找cons单元格中的第二个成员。

答案 1 :(得分:7)

根据C来思考,lisp对只是struct,包含两个字段carcdr。 lisp函数carcdr仅用于访问每个字段。

以下是对part of Racket's scheme.h的了解:

typedef struct Scheme_Simple_Object
{
  Scheme_Inclhash_Object iso;

  union
    {
      struct { mzchar *string_val; intptr_t tag_val; } char_str_val;
      struct { char *string_val; intptr_t tag_val; } byte_str_val;
      struct { void *ptr1, *ptr2; } two_ptr_val;
      struct { int int1; int int2; } two_int_val;
      struct { void *ptr; int pint; } ptr_int_val;
      struct { void *ptr; intptr_t pint; } ptr_long_val;
      struct { struct Scheme_Object *car, *cdr; } pair_val;
      struct { mzshort len; mzshort *vec; } svector_val;
      struct { void *val; Scheme_Object *type; } cptr_val;
    } u;
} Scheme_Simple_Object;

请注意union

的这一部分
      struct { struct Scheme_Object *car, *cdr; } pair_val;

你发现later in scheme.h

#define SCHEME_CAR(obj)      (((Scheme_Simple_Object *)(obj))->u.pair_val.car)
#define SCHEME_CDR(obj)      (((Scheme_Simple_Object *)(obj))->u.pair_val.cdr)

当然,Racket cdr函数将比这个C宏做更多的工作,例如检查它是否被赋予pair?

答案 2 :(得分:1)

球拍definition of a paircarcdr对话作为配对存取,因此间接将其指定为O(1)。要使cdr成为O(n),你必须将其反转为butlast并且不符合球拍文档。

球拍母语,Scheme,有一个R6RS spec,其中carcdrpair中的字段的访问者,也是间接的O(1)。

Common Lisp中,Scheme的菜肴有类似的描述,唯一的区别是他们在规范中使用名称cons而不是pair。 (你标记了lisp)

虽然这并不是特意,因为cons / pairs是由所有LISP的母亲John McCarthy's LISP定义的基本数据类型,并且它的第一个实现具有检索某些东西的汇编指令名为address and decrement from a memory locationcar / cdr中的字母a和d来自该术语。