如何使用C語言寫: Generic Queue

來源:互聯網
上載者:User

Model

------------------------------------------------------------------------------------------------------------------------

隊列也是限制插入和刪除位元置的表.

主要操作是enqueue和dequeue操作.

enqueue:入隊操作.在表的隊尾(rear)插入一個元素.

dequeue:出隊操作.刪除表的隊首(front)元素.

 

本文使用迴圈數組實現GenericQueue.需要指定capacity.缺點是超出容量,無法動態增長.當然,可以仿照list的方式克服這個問題.

 完整代碼詳見我的github(https://github.com/gnudennis/ds_c)(genric-queue.h
generic-queue.c generic-queue-test.c)

 

核心代碼

------------------------------------------------------------------------------------------------------------------------

0. Generic Queue定義

typedef void *ElementAddr;typedef void (*PfCbFree)(ElementAddr);typedef struct QueueRecord{        ElementAddr*array;        intcapacity;        intelemsize;        intfront;        intrear;        intsize;        PfCbFreefreefn;} *Queue;

1. API

/* Create a new queue */Queue queue_create(int elemsize, int capacity, PfCbFree freefn);/* Dispose the queue */void queue_dispose(Queue que);/* Make the give queue empty */void queue_make_empty(Queue que);/* Return true if the queue is empty */int queue_is_empty(Queue que);/* Return true if the queue is full */int queue_is_full(Queue que);/* Insert a new element onto queue */void queue_enqueue(Queue que, ElementAddr elemaddr);/* Delete the front element off the queue */void queue_dequeue(Queue que);/* Fetch the front element from the queue */void queue_front(Queue que, ElementAddr elemaddr);/* Fetch and Delete the front element from the queue */void queue_front_and_dequeue(Queue que, ElementAddr elemaddr);

2.Implementation

/* Create a new queue with capacity */Queue queue_create(int elemsize, int capacity, PfCbFree freefn){        Queue que;        que = malloc(sizeof(struct QueueRecord));        if ( que == NULL ) {                fprintf(stderr, "Out of memory\n");                exit(1);        }                que->elemsize = elemsize;        que->capacity = capacity > MIN_QUEUE_SIZE ? capacity : MIN_QUEUE_SIZE;        que->array = malloc(elemsize * que->capacity);        if ( que->array == NULL ) {                fprintf(stderr, "Out of memory\n");                exit(1);        }        que->front = 1;        que->rear = 0;        que->size = 0;        que->freefn = freefn;        return que;}/* Dispose the queue */void queue_dispose(Queue que){        if (que != NULL) {                queue_make_empty(que);                free(que->array);                free(que);        }}/* Make the give queue empty */void queue_make_empty(Queue que){        if ( que->freefn ) {                int i;                for ( i = 0; i < que->size; ++i) {                        free((char *)que->array +                              que->elemsize * i);                }        }        que->size = 0;        que->front = 1;        que->rear = 0;}/* Return true if the queue is empty */int queue_is_empty(Queue que){        return que->size == 0;}/* Return true if the queue is full */int queue_is_full(Queue que){        return que->size == que->capacity;}static int successor(Queue que, int index){        if ( ++index == que->capacity)                index = 0;        return index;}/* Insert a new element onto queue(rear) */void queue_enqueue(Queue que, ElementAddr elemaddr){        void *target;        if ( queue_is_full(que) ) {                fprintf(stderr, "Full queue\n");                exit(1);        }        que->rear = successor(que, que->rear);        target = (char *)que->array + que->elemsize * que->rear;        memcpy(target, elemaddr, que->elemsize);        que->size++;}/* Delete the front element off the queue */void queue_dequeue(Queue que){        if ( queue_is_empty(que) ) {                fprintf(stderr, "Empty queue\n");                exit(1);        }        if ( que->freefn ) {                void *target = (char *)que->array +                               que->front * que->elemsize;                que->freefn(target);        }        que->size--;        que->front = successor(que, que->front);}/* Fetch the front element from the queue */void queue_front(Queue que, ElementAddr elemaddr){        void *target = (char *)que->array +                        que->front * que->elemsize;        memcpy(elemaddr, target, que->elemsize);}/* Fetch and Delete the front element from the queue */void queue_front_and_dequeue(Queue que, ElementAddr elemaddr){        void *target;        if ( queue_is_empty(que) ) {                fprintf(stderr, "Empty queue\n");                exit(1);        }        target = (char *)que->array +                        que->front * que->elemsize;        memcpy(elemaddr, target, que->elemsize);        que->size--;        que->front = successor(que, que->front);}

分析

----------------

本文使用迴圈數組實現GenericQueue.需要指定capacity.既然是迴圈數組,就是圍成一個圈.也就插入第一個元素沒有必要非要放在0處啦.

初始狀態:

{

que->size = 0;

que->front = 1;

que->rear = 0;

}

說明這樣第一次enqueue操作放在array[1]處,當然:這不是必須的,取決於你想放在那裡.

#define mxx

{

que->size = 0;

que->front =m+1;

que->rear = m;

}

就放在array[m+1]處.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.