C.Interface.And.Implementations—sequence的实现

1、A sequence holds  N  values associated with the integer indices zero through N−1 when  N is positive. 

2、An empty sequence holds no values. 

3、Like arrays, values in a sequence may be accessed by indexing; 

4、they can also be added to or removed from either end of a sequence. 

5、Sequences expand automatically as necessary to accommodate their contents. Values are pointers.

6、they can be used as arrays, lists, stacks, queues, and deques, and they often subsume the facilities of separate
      ADTs for these data structures.


sequence底层数据结构如下图所示:

                    

其中左边部分阴影为上一节“dynamic array”,length为sequence中目前的元素总共数目,head为array中第一个元素的位置。可以看出,通过循环的dynamic array来实现sequence的。


==========================seq.h=============================

#ifndef SEQ_INCLUDED
#define SEQ_INCLUDED

#define T Seq_T
typedef struct T *T;

//exported functions
extern T      Seq_new   (int hint);
extern T      Seq_seq   (void *x, ...);
extern void   Seq_free  (T *seq);
extern int    Seq_length(T seq);
extern void  *Seq_get   (T seq, int i);
extern void  *Seq_put   (T seq, int i, void *x);
extern void  *Seq_addlo (T seq, void *x);
extern void  *Seq_addhi (T seq, void *x);
extern void  *Seq_remlo (T seq);
extern void  *Seq_remhi (T seq);

#undef T
#endif

======================seq.c==========================

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "assert.h"
#include "seq.h"
#include "array.h"
#include "arrayrep.h"
#include "mem.h"

#define T Seq_T

struct T{
    struct Array_T  array;
    int length;
    int head;
};

//static functions
static void expand(T seq){
    int n = seq->array.length;

    Array_resize(&seq->array, 2*n);
    if(seq->head > 0)
    {
        void **old = &((void **)seq->array.array)[seq->head];
        memcpy(old+n, old, (n-seq->head)*sizeof(void *));
        seq->head += n;
    }
}

//functions
T Seq_new(int hint){
    T seq;

    assert(hint >= 0);
    NEW0(seq);
    if(hint == 0)
        hint = 16;
    ArrayRep_init(&seq->array, hint, sizeof(void *),
        ALLOC(hint*sizeof(void *)));
    return seq;
}

T Seq_seq(void *x, ...){
    va_list ap;
    T seq = Seq_new(0);

    va_start(ap, x);
    for( ; x; x = va_arg(ap, void *))
        Seq_addhi(seq, x);
    va_end(ap);
    return seq;
}

void Seq_free(T *seq){
    assert(seq && *seq);
    assert((void *)*seq == (void *)&(*seq)->array);
    Array_free((Array_T *)seq);
}

int Seq_length(T seq){
    assert(seq);
    return seq->length;
}

void *Seq_get(T seq, int i){
    assert(seq);
    assert(i >= 0 && i < seq->length);
    return ((void **)seq->array.array)[
        (seq->head + i)%seq->array.length];
}

void *Seq_put(T seq, int i, void *x){
    void *prev;

    assert(seq);
    assert(i >= 0 && i < seq->length);
    prev = ((void **)seq->array.array)[
        (seq->head + i)%seq->array.length];
    ((void **)seq->array.array)[
        (seq->head + i)%seq->array.length] = x;
    return prev;
}

void *Seq_remhi(T seq){
    int i;

    assert(seq);
    assert(seq->length > 0);
    i = --seq->length;
    return ((void **)seq->array.array)[
        (seq->head+i)%seq->array.length];
}

void *Seq_remlo(T seq){
    int i = 0;
    void *x;

    assert(seq);
    assert(seq->length > 0);
    x = ((void **)seq->array.array)[
        (seq->head+i)%seq->array.length];
    seq->head = (seq->head + 1)%seq->array.length;
    --seq->length;
    return x;
}

void *Seq_addhi(T seq, void *x){
    int i;

    assert(seq);
    if(seq->length == seq->array.length)
        expand(seq);
    i = seq->length++;
    return ((void **)seq->array.array)[
        (seq->head+i)%seq->array.length] = x;
}

void *Seq_addlo(T seq, void *x){
    int i = 0;

    assert(seq);
    if(seq->length == seq->array.length)
        expand(seq);
    if(--seq->head < 0)
        seq->head = seq->array.length-1;
    seq->length++;
    return ((void **)seq->array.array)[
        (seq->head+i)%seq->array.length] = x;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值