数据结构手把手教学——循环队列

一、队列

1、队列特点:

①、线性结构、具有队头和队尾,有且只有一个直接前驱和直接后继。
②、只允许在一段插入(入队)、另一端删除(出队),且先进先出


二、循环队列

顺序队列是队列得顺序存储结构,通过改进后成为循环队列。

数据结构手把手教学——循环队列_第1张图片

1、规定

①、front表示队头得前一个位置下标。
②、rear表示队尾位置下标。
③、队列空时:front = rear

2、改进后循环队列

数据结构手把手教学——循环队列_第2张图片


三、用C语言实现顺序队列

1、构造存储结构
#define SIZE 8
typedef int datatype;
typedef struct seqqueue
{
     
    datatype data[SIZE];   // 数据域
    int front;  // 队头前一个位置下标
    int rear;   // 队尾位置下标
}seq_queue, *seq_pqueue;
2、初始化

①申请内存空间
②front = rear = SIZE - 1

void init_seqqueue(seq_pqueue *queue)
{
     
    (*queue) = (seq_pqueue)malloc(sizeof(seq_queue));

    if (NULL == (*queue))
    {
     
        perror("malloc");
        exit(1);
    }

    (*queue)->front = SIZE - 1;
    (*queue)->rear = SIZE - 1;
}
3、入队

①、改进前入队方式

rear++;
data[rear] = dat;

假设设定得队列SIZE = 8,我们知道初始化得时候rear = -1,当rear++7的时候就已经入队满了,如果此时有人出队,再想入队,rear++会等于8,溢出不能入队。
数据结构手把手教学——循环队列_第3张图片

②、改进的入队方式

rear = (rear + 1) % SIZE;
data[rear] = dat;

③、入队前先判断队列是否已满

判断front = (rear + 1)%SIZE;是否成立。

bool isfull_seqqueue(seq_pqueue queue)
{
     
    if (queue->front == (queue->rear + 1) % SIZE)
    {
     
        return true;
    }
    else
    {
     
        return false;
    }
}

④、入队实现代码

void in_seqqueue(seq_pqueue queue, datatype dat)
{
     
    if (isfull_seqqueue(queue))
    {
     
        printf("队列已满\n");
        return;
    }
    
    queue->rear = (queue->rear + 1) % SIZE;
    queue->data[queue->rear] = dat;
}
4、出队

根据前面入队分析,同理可以知道入队方式:
front = (front + 1)%SIZE;
*dat = data[front];

①、出队前先判断队列是否已空。

front = rear的时候表示队列已空。

bool isempty_seqqueue(seq_pqueue queue)
{
     
    if (queue->front == queue->rear)
    {
     
        return true;
    }
    else
    {
     
        return false;
    }
}

②、出队实现代码

void out_seqqueue(seq_pqueue queue, datatype *dat)
{
     
    if (isempty_seqqueue(queue))
    {
     
        printf("队列已空\n");
        return;
    }

    queue->front = (queue->front + 1) % SIZE;
    *dat = queue->data[queue->front];
}
5、打印
void show_seqqueue(seq_pqueue queue)
{
     
    int i = 0;

    for (i = (queue->front + 1) % SIZE; i != (queue->rear + 1) % SIZE; i = (i + 1) % SIZE)
    {
     
        printf("%d\t", queue->data[i]);
    }

    printf("\n");
}

四、练习题

用户从键盘输入整数,程序将其入队,用户输入字母,程序将队头元素出队,并在每一次出队和入队之后打印队列元素。

1、实现代码
int main(void)
{
     
    seq_pqueue queue = NULL;
    datatype in_data = 0;
    datatype out_data = 0;
    int ret = 0;

    init_seqqueue(&queue);  // 初始化队列

    while (1)
    {
     
        printf("输入整数:");
        ret = scanf("%d", &in_data);

        if (ret != 0)
        {
     
            in_seqqueue(queue, in_data);
            printf("入队后队列元素:");
            show_seqqueue(queue);
        }
        else
        {
     
            out_seqqueue(queue, &out_data);
            printf("出队后队列元素:");
            show_seqqueue(queue);
            while(getchar() != '\n');   // 清空输入缓冲
        }
    }

    return 0;
}
2、结果

数据结构手把手教学——循环队列_第4张图片


五、完整代码

https://github.com/sanjaywu/DataStructure

你可能感兴趣的:(数据结构与算法,循环队列)