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

1、A ring  is much like a sequence: It holds N values associated with the integer indices zero through N −1 when N is positive. 

2、An empty ring holds no values. Values are pointers. 

3、Like the values in a sequence, values in a ring may be accessed by indexing.

4、Unlike a sequence, however, values can be added to a ring anywhere , and any  value in a ring can be removed. 5、In addition, the values can be renumbered: “rotating” a ring left decrements the index of each value by one modulo the length of the ring; rotating it right increments the indi-ces by one modulo the ring length. 

6、The price for the flexibility of adding values to and removing values from arbitrary locations in a ring is that accessing the  i th value is not guaranteed to take constant time.


简单而言,ring就是一个“环”,底层用“双向链表”进行实现。


                       C.Interface.And.Implementations—ring的实现_第1张图片

在环中的位置定义:

                         C.Interface.And.Implementations—ring的实现_第2张图片

一个带有六个元素的示意图:

C.Interface.And.Implementations—ring的实现_第3张图片

插入一个新结点的示意图:

C.Interface.And.Implementations—ring的实现_第4张图片

删除结点的示意图:

                     C.Interface.And.Implementations—ring的实现_第5张图片

=========================ring.h=========================

#ifndef RING_INCLUDED
#define RING_INCLUDED

#define T Ring_T
typedef struct T *T;

//exported functions
extern T     Ring_new   (void);
extern T     Ring_ring  (void *x, ...);
extern void  Ring_free  (T *ring);
extern int   Ring_length(T ring);
extern void *Ring_get   (T ring, int i);
extern void *Ring_put   (T ring, int i, void *x);
extern void *Ring_add   (T ring, int pos, void *x);
extern void *Ring_addlo (T ring, void *x);
extern void *Ring_addhi (T ring, void *x);
extern void *Ring_remove(T ring, int i);
extern void *Ring_remlo (T ring);
extern void *Ring_remhi (T ring);
extern void  Ring_rotate(T ring, int n);

#undef T
#endif

========================ring.c=============================

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "assert.h"
#include "ring.h"
#include "mem.h"

#define T Ring_T

struct T{
    struct node{
        struct node *llink, *rlink;
        void *value;
    } *head;
    int length;
};

//functions
T Ring_new(void){
    T ring;

    NEW0(ring);
    ring->head = NULL;
    return ring;
}

T Ring_ring(void *x, ...){
    va_list ap;
    T ring = Ring_new();

    va_start(ap, x);
    for(; x; x = va_arg(ap, void *))
        Ring_addhi(ring, x);
    va_end(ap);

    return ring;
}

void Ring_free(T *ring){
    struct node *p, *q;

    assert(ring && *ring);
    if((p = (*ring)->head) != NULL){
        int n = (*ring)->length;
        for(; n-- > 0; p = q){
            q = p->rlink;
            FREE(p);
        }
    }

    FREE(*ring);
}


int Ring_length(T ring){
    assert(ring);
    return ring->length;
}

void *Ring_get(T ring, int i){
    struct node *q;

    assert(ring);
    assert(i >= 0 && i < ring->length);
    //q <- ith node
    {
        int n;
        q = ring->head;
        if(i < ring->length/2){
            for(n = i; n-- > 0; )
                q = q->rlink;
        }else{
            for(n = ring->length - i; n-- > 0; )
                q = q->llink;
        }
    }
    return q->value;
}

void *Ring_put(T ring, int i, void *x){
    struct node *q;
    void *prev;

    assert(ring);
    assert(i >= 0 && i < ring->length);
    //q <- ith node
    {
        int n;
        q = ring->head;
        if(i <= ring->length/2){
            for(n = i; n-- > 0; )
                q = q->rlink;
        }else{
            for(n = ring->length - i; n-- > 0; )
                q = q->llink;
        }
    }
    prev = q->value;
    q->value = x;
    return prev;
}

void *Ring_addhi(T ring, void *x){
    struct node *p, *q;

    assert(ring);
    NEW(p);
    if((q = ring->head) != NULL){
        p->llink = q->llink;
        q->llink->rlink = p;
        p->rlink = q;
        q->llink = p;
    }else{
        ring->head = p->llink = p->rlink = p;
    }
    ring->length++;
    return p->value = x;
}

void *Ring_addlo(T ring, void *x){
    assert(ring);
    Ring_addhi(ring, x);
    ring->head = ring->head->llink;
    return x;
}

void *Ring_add(T ring, int pos, void *x){
    assert(ring);
    assert(pos >= -ring->length && 
       pos <= ring->length+1);
    if(pos == 1 || pos == -ring->length)
        return Ring_addlo(ring, x);
    else if(pos == 0 || pos == ring->length + 1)
        return Ring_addhi(ring, x);
    else{
        struct node *p, *q;
        int i = pos < 0 ? pos + ring->length : pos - 1;
        //q <- ith node
        {
            int n;
            q = ring->head;
            if(i <= ring->length/2){
                for(n = i; n-- > 0; )
                    q = q->rlink;
            }else{
                for(n = ring->length - i; n-- > 0; )
                    q = q->llink;
            }
        }
        NEW(p);
        //insert p to the left of q
        {
            p->llink = q->llink;
            q->llink->rlink = p;
            p->rlink = q;
            q->llink = p;
        }
        ring->length++;
        return p->value = x;
    }
}

void *Ring_remove(T ring, int i){
    void *x;
    struct node *q;

    assert(ring);
    assert(ring->length > 0);
    assert(i >= 0 && i < ring->length);
    //q <- ith node
    if(i == 0)
        ring->head = ring->head->rlink;
    x = q->value;
    //delete node q
    q->llink->rlink = q->rlink;
    q->rlink->llink = q->llink;
    FREE(q);
    if(--ring->length == 0)
        ring->head = NULL;
    return x;
}

void *Ring_remhi(T ring){
    void *x;
    struct node *q;

    assert(ring);
    assert(ring->length > 0);
    q = ring->head->llink;
    x = q->value;
    //delete node q
    q->llink->rlink = q->rlink;
    q->rlink->llink = q->llink;
    FREE(q);
    if(--ring->length == 0)
        ring->head = NULL;
    return x;
}

void *Ring_remlo(T ring){
    assert(ring);
    assert(ring->length > 0);
    ring->head = ring->head->rlink;
    return Ring_remhi(ring);
}

void Ring_rotate(T ring, int n){
    struct node *q;
    int i;

    assert(ring);
    assert(n >= -ring->length &&
        n <= ring->length);
    if(n >= 0)
        i = n%ring->length;
    else
        i = n + ring->length;
    //q <- ith node
    {
        int n;
        q = ring->head;
        if( i <= ring->length/2){
            for(n = i; n-- > 0; )
                q = q->rlink;
        }else{
            for(n = ring->length - i; n-- > 0; )
                q = q->llink;
        }
    }
    ring->head = q;
}


你可能感兴趣的:(c,interface,ring)