1. 程式人生 > >環形佇列c語言程式碼

環形佇列c語言程式碼

這段程式碼實現了一個環形佇列,資料型別可以根據自己的需要更改,這裡預留的是指標型別。

ring_queue.h

#ifndef _RINGQUEUE_
#define _RINGQUEUE_

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

// 佇列包含的資訊
typedef struct queue
{
    char **qu;      //用來儲存全部的佇列中的元素
    int head;     //佇列頭
    int tail;     //隊尾
    int qlength;  //佇列長度
    int maxsize;  //用來記錄佇列的最大容量

}RQUEUE;

RQUEUE  *rq_init ( RQUEUE *q, char **qu, int maxsize );
bool rq_full (RQUEUE *q);
bool rq_empty(RQUEUE *q);
bool rq_front(RQUEUE *q, char **data);
bool rq_back (RQUEUE *q, char **data);
bool rq_push (RQUEUE *q, char *data);
bool rq_pop  (RQUEUE *q, char **data);
int rq_size  (RQUEUE *q);
//------------------
void rq_traverse(RQUEUE *q);

#endif

ring_queue.c

#include "ring_queue.h"

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define  RQMAXSIZE  5
#define  DMAXSIZE  8
//  初始化佇列
RQUEUE  *rq_init ( RQUEUE *q, char **qu, int maxsize )
{
    printf("rq_init\tin[%lu]\n",sizeof(RQUEUE));

    if (q == NULL) {
        printf("Memory alloc failure\n");
        return(NULL);
    }

	q->qu = qu;
    if(NULL==q->qu)
    {
        printf("Memory allocation failure");
        return(NULL);        //退出程式
    }
    //分配完空間後,1開始隊頭隊尾都在一起,因為沒人,都為0長度也為0,
    q->head = 0;
    q->tail = 0;
    q->qlength = 0;
    q->maxsize = maxsize;

	printf("rq_init\tout\n");
    return q;
}

// 判斷空佇列,長度為0則為空
bool rq_empty (RQUEUE *q)
{
    return  q->qlength == 0 ? true : false;
}

// 判斷滿佇列,長度=最大容量為滿
bool rq_full (RQUEUE *q)
{
    return q->qlength == q->maxsize ? true : false;
}

//入隊
bool rq_push (RQUEUE *q, char *data)
{
	printf("rq_push in %s\n", data);
    // 佇列不滿才插入
    if (rq_full(q)) {
        printf("佇列滿了,插入失敗\n");
        return false;

    }else{
        //給隊伍最尾新增賦值。
        //q->qu[q->tail] = num;
		printf("%d \n",  q->tail);
		char (*p)[DMAXSIZE] = (char(*)[DMAXSIZE])q->qu;
		memcpy(p[q->tail], data, DMAXSIZE);
        //隊尾向後移動一位,如果超過最大值,則從0開始,變成隊尾
        q->tail = (q->tail +1)%q->maxsize;
        //隊伍長度+1
        q->qlength++;
		printf("rq_push\tout\n");
        return true;
    }

}

// 出隊
bool rq_pop (RQUEUE *q, char **data)
{
	printf("rq_pop\tin\n");
    // 佇列有元素才能夠刪除
    if (rq_empty(q)) {
        printf("佇列為空,刪除失敗\n");
        return false;
    }else{
		char (*p)[DMAXSIZE] = (char(*)[DMAXSIZE])q->qu;
		*data = p[(q->head)];
        //隊頭向後移動一位 超過最大值又重新 從0 開始計算
        q->head = (q->head +1)%q->maxsize;
		
        // 隊伍長度-1
        q->qlength--;
		printf("rq_pop\tout\n");
        return true;
    }
}

//佇列已有資料
int rq_size(RQUEUE *q)
{
	return q->qlength;
}

//佇列中頭元素
bool rq_front(RQUEUE *q, char **data)
{
	printf("rq_front\tin\n");
    // 佇列有元素才能夠刪除
    if (rq_empty(q)) {
        printf("佇列為空,查詢失敗\n");
        return false;
    }else{
		char (*p)[DMAXSIZE] = (char(*)[DMAXSIZE])q->qu;
		*data = p[(q->head)];
		printf("rq_front\tout\n");
        return true;
    }
}

//佇列中尾元素
bool rq_back (RQUEUE *q, char **data)
{
	printf("rq_back\tin\n");
    // 佇列有元素才能夠刪除
    if (rq_empty(q)) {
        printf("佇列為空,查詢失敗\n");
        return false;
    }else{
		char (*p)[DMAXSIZE] = (char(*)[DMAXSIZE])q->qu;
		*data = p[(q->tail+q->maxsize-1)%q->maxsize];
		printf("rq_back\tout\n");
        return true;
    }
}

// 遍歷佇列元素
void rq_traverse(RQUEUE *q)
{
	printf("rq_traverse\tin\n");
	char (*p)[DMAXSIZE] = (char(*)[DMAXSIZE])q->qu;
    // 在佇列長度範圍內 列印佇列從佇列頭 到佇列尾的元素
    for (int i=0 ; i<q->qlength; i++) {
      printf("%s ",  p[(q->head+i)%q->maxsize]);
    }
    printf("\n");
	printf("rq_traverse\tout\n");
}

int main(int argc, const char * argv[]) {
    // insert code here...
	printf("main\tin\n");

	RQUEUE Q;
	char a[RQMAXSIZE][DMAXSIZE];
	printf("%ld\n", ARRAY_SIZE(a));
    rq_init(&Q, (char **)a, ARRAY_SIZE(a));
    if ( rq_empty(&Q)) {
        printf("空佇列\n");
    };

	char *c = NULL;
	rq_front(&Q, &c);
	printf("%s \n",  c);
	rq_back (&Q, &c);
	printf("%s \n",  c);
	
	char *aa = "1111111";

    rq_push(&Q, aa);
	aa = "2222222";
    rq_push(&Q, aa);
	aa = "3333333";
    rq_push(&Q, aa);
    if ( rq_empty(&Q)) {
        printf("空佇列\n");
    };

	rq_front(&Q, &c);
	printf("%s \n",  c);
	rq_back (&Q, &c);
	printf("%s \n",  c);
	aa = "444444";
    rq_push(&Q, aa);
	aa = "555555";
    rq_push(&Q, aa);


    rq_pop(&Q, &c);
	printf("rq_pop = %s \n",  c);
	aa = "666666";
    rq_push(&Q, aa);
	aa = "77777";
	rq_push(&Q, aa);

    if (rq_full(&Q)) {
        printf("滿佇列\n");
    }

    rq_traverse(&Q);
	
	rq_front(&Q, &c);
	printf("%s \n",  c);
	rq_back (&Q, &c);
	printf("%s \n",  c);

    return 0;
}

編譯檢視執行結果gcc ring_queue.c -o ring_q

[email protected]:~/ring_queue$ ./ring_q
main	in
5
rq_init	in[20]
rq_init	out
空佇列
rq_front	in
佇列為空,查詢失敗
(null) 
rq_back	in
佇列為空,查詢失敗
(null) 
rq_push in 1111111
0 
rq_push	out
rq_push in 2222222
1 
rq_push	out
rq_push in 3333333
2 
rq_push	out
rq_front	in
rq_front	out
1111111 
rq_back	in
rq_back	out
3333333 
rq_push in 444444
3 
rq_push	out
rq_push in 555555
4 
rq_push	out
rq_pop	in
rq_pop	out
rq_pop = 1111111 
rq_push in 666666
0 
rq_push	out
rq_push in 77777
佇列滿了,插入失敗
滿佇列
rq_traverse	in
2222222 3333333 444444 555555 666666 
rq_traverse	out
rq_front	in
rq_front	out
2222222 
rq_back	in
rq_back	out
666666