day8 队列实现及其应用(上)

顺序队列的原理

队列

定义:队列是限制在两端进行插入操作和删除操作的线性表

允许进行存入操作的一端称为“队尾”;

允许进行删除操作的一端称为“队头”;

当线性表中没有元素时,称为“空队”

特点:先进先出(FIFO)

双端队列:可以左边入左边出右边入右边出也可以左边入右边出右边入左边出;如果固定一端另一端操作可以看做是一个

循环队列

规定:front 指向队头元素的位置;rear指向队尾的元素的下一个位置。

在队列操作过程中,为了提高效率,以调整指针代替队列元素的移动,并将数组作为循环队列的操作空间。

为区别空队和满队,满队元素个数比数组元素个数少一个。

顺序队列

顺序队列数据结构体声明

typedef int datatype;
#define N 128

typedef struct {
    datadype data[N];
    int front;
    int rear;
}sequeue;

顺序队列的创建操作

函数原型

sequeue * queue_create();

算法思路:首先利用malloc创建顺序队列空间,然后利用memset函数对队列数据初始化。

代码实现:

sequeue * queue_create() {
    sequeue *sq;
    
    if ((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL) {
        printf("malloc falied\n");
        return NULL;
    }

    memset(sq->data, 0, sizeof(data));
    sq->front = sq->rear = 0;
    return sq;
}

入队操作

函数原型:

int enqueue *sq, datatype x);

算法思路:

(1)判断队列是否已满;

(2)rear是指示队尾元素的下一个位置,即存放新值的位置,rear的位置先存入值然后rear在移动,如图1所示;

(3)当N = 6,rear = 5时,队列虽然可以继续存数,但是rear++就会超出队列范围,则需要rear+1对N取余进行0~5之间循环,如图2所示

注意:为区别空队和满队,满队元素个数比数组元素个数少一个。

图 1

图 2

代码实现:

int enqueue(sequeue *sq, datatype x) {
    if (sq == NULL) {
        printf("sq is BULL\n");
        return -1;
    }
//检查队列是否已满
    if ((sq->rear + 1) % N == sq->front) {
        printf("sequeue is full\n");
        return -1;
    }
//存入新值,rear移动
    sq->data[sq->rear] = x;
    sq->rear = (sq->rear + 1) % N;
    
    return 0;
}

出队操作

函数原型:

datatype dequeue(sequeue * sq);

算法思路:

(1)出队时,front的移动与rear相同也是需要((front+1) % N)对N取余;

(2)出队时需要返回队头值,另外front移动一个队内的值不会被覆盖可以找一个中间变量接收队头;

(3)更新队列。

代码实现:

datatype dequeue(sequeue *sq) {
    datatype ret;
    ret = sq->data[sq->front];
    sq->front = (sq->front + 1) % N;
    return ret;
}

判断队列是空还是满操作

函数原型:

int queue_empty(sequeue *sq);
int queue_full(sequeue *sq);

代码实现:

int queue_empty(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is BULL\n");
        return -1;
    }

    return(sq->front == sq->rear ? 1 : 0);
}
/*-----------------------------------------------**/
int queue_full(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is BULL\n");
        return -1;
    }
    if (sq->rear + 1) % N == sq->front) {
        return 1;
    }
    else{
        return 0;
    }
}

队列置空操作

函数原型:

int queue_clear(sequeue *sq);

代码实现:

int queue_clear(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is BULL\n");
        return -1;
    }
    sq->front = sq->rear = 0;
    return 0;
}

队列空间释放

函数原型:

sequeue * queue_free(sequue *sq) {
    if (sq == NULL) {
     printf("sq is BULL\n");
        return -1;
    }
    free(sq);
    sq = NULL;
    return NULL;
}

顺序队列实现整体代码

sequeue.h

typedef int datatype;
#define N 128

typedef struct {
    datatype data[N];
    int front;
    int rear;
}sequeue;

sequeue * queue_create();
int enqueue(sequeue *sq, datatype x);
datatype dequeue(sequeue *sq);
int queue_empty(sequeue *sq);
int queue_full(sequeue *sq); 
int queue_clear(sequeue *sq);
sequeue * queue_free(sequeue *sq);

sequeue.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"

sequeue * queue_create() {
    sequeue *sq;

    if ((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL) {
        printf("malloc failed\n");
        return NULL;
    }

    memset(sq->data, 0, sizeof(sq->data));
    sq->front = sq->rear = 0;
    return sq;
}

int enqueue(sequeue *sq, datatype x) {
    if (sq == NULL) {
        printf("sq is NULL\n");
        return -1;
    }

    if ((sq->rear + 1) % N == sq->front) {
        printf("sequeue is full\n");
        return -1;
    }

    sq->data[sq->rear] = x;
    sq->rear = (sq->rear + 1) % N;

    return  0;
}

datatype dequeue(sequeue *sq) {
    datatype ret;

    ret = sq->data[sq->front];

    sq->front = (sq->front + 1) % N;

    return ret;
}

int queue_empty(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is NULL\n");
        return -1;
    }

    return (sq->front == sq->rear ? 1 : 0);
}

int queue_full(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is NULL\n");
        return -1;
    }

    if ((sq->rear + 1) % N == sq->front) {
        return 1;
    }
    else {
        return 0;
    }
}

int queue_clear(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is NULL\n");
        return -1;
    }

    sq->front = sq->rear = 0;

    return 0;
}

sequeue * queue_free(sequeue *sq) {
    if (sq == NULL) {
        printf("sq is NULL\n");
        return NULL;
    }

    free(sq);
    sq = NULL;

    return NULL;
}

main.c

#include <stdio.h>
#include "sequeue.h"

int main(int argc, const char *argv[])
{
    sequeue *sq;

    if ((sq = queue_create()) == NULL) {
        return -1;
    }
    
    enqueue(sq, 10);
    enqueue(sq, 100);
    enqueue(sq, 1000);

    while (!queue_empty(sq)) {
        printf("dequeue:%d\n", dequeue(sq));
    }

    queue_free(sq);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值