实现一个循环队列

这段代码实现了一个循环队列的基本操作,包括初始化队列、入队、出队和查看队列的第一个元素。

代码:

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

// 定义队列结构体
typedef struct {
    int* queue;       // 存储队列元素的数组指针
    int top;          // 队列头部索引(出队的位置)
    int bottom;       // 队列尾部索引(入队的位置)
    int queuenum;     // 队列中元素的数量(未使用)
    int queuemax;     // 队列的最大长度
} stQueue;

// 初始化队列函数
void queue_init(stQueue* st, int maxlen) {
    if (st->queue == NULL) {
        // 为队列分配内存空间,长度为 maxlen + 1
        st->queue = (int*)malloc((maxlen + 1) * sizeof(int));
        st->queuemax = maxlen + 1;  // 设置队列最大长度
        st->bottom = 0;  // 初始化队列尾部索引
        st->top = 0;     // 初始化队列头部索引
        st->queuenum = 0;  // 初始化队列元素数量(未使用)
    }
}

// 入队函数
int queue_push(stQueue* st, int data) {
    int ret = -1;  // 默认返回 -1 表示失败
    // 判断队列是否已满
    if ((st->bottom + 1) % (st->queuemax) == st->top) {
        printf("full\n");  // 打印队列已满
    } else {
        // 将数据存入队列尾部
        st->queue[st->bottom] = data;
        // 更新队列尾部索引,实现循环
        st->bottom = (st->bottom + 1) % st->queuemax;
        ret = 0;  // 入队成功返回 0
    }
    return ret;
}

// 出队函数
int queue_pop(stQueue* st) {
    int ret = -1;  // 默认返回 -1 表示失败
    // 判断队列是否为空
    if (st->bottom == st->top) {
        printf("empty\n");  // 打印队列为空
    } else {
        // 打印队列头部元素
        printf("%d\n", st->queue[st->top]);
        // 更新队列头部索引,实现循环
        st->top = (st->top + 1) % st->queuemax;
        ret = 0;  // 出队成功返回 0
    }
    return ret;
}

// 查看队列头部元素函数
int queue_front(stQueue* st) {
    int ret = -1;  // 默认返回 -1 表示失败
    // 判断队列是否为空
    if (st->bottom == st->top) {
        printf("empty\n");  // 打印队列为空
    } else {
        // 打印队列头部元素
        printf("%d\n", st->queue[st->top]);
        ret = 0;  // 查看成功返回 0
    }
    return ret;
}

// 主函数
int main() {
    char op[100] = {0};  // 操作命令缓冲区
    unsigned int n, q = 0;  // 队列长度和操作数量
    stQueue stMyqueue = {0};  // 初始化队列结构体
    scanf("%d %d", &n, &q);  // 输入队列长度 n 和操作数量 q
    queue_init(&stMyqueue, n);  // 初始化队列
    for (unsigned int i = 0; i <= q; i++) {
        fgets(op, sizeof(op), stdin);  // 读取操作命令
        if (strstr(op, "push")) {
            // 如果命令是 push,调用入队函数
            queue_push(&stMyqueue, atoi(op + 5));
        } else if (strstr(op, "pop")) {
            // 如果命令是 pop,调用出队函数
            queue_pop(&stMyqueue);
        } else if (strstr(op, "front")) {
            // 如果命令是 front,调用查看函数
            queue_front(&stMyqueue);
        }
    }
    return 0;
}

1. 数据结构定义

typedef struct {
    int* queue;       // 存储队列元素的数组指针
    int top;          // 队列头部(出队的位置)
    int bottom;       // 队列尾部(入队的位置)
    int queuenum;     // 当前队列中的元素数量(代码中未使用)
    int queuemax;     // 队列的最大长度
} stQueue;
  • stQueue 是一个结构体,定义了一个队列的基本属性:
    • queue: 用于存储队列元素的动态数组。
    • top: 队列的头部索引,用于出队操作。
    • bottom: 队列的尾部索引,用于入队操作。
    • queuenum: 队列中元素的数量(但在代码中没有实际使用这个字段)。
    • queuemax: 队列的最大长度。

2. 队列初始化函数

void queue_init(stQueue* st, int maxlen) {
    if (st->queue == NULL) {
        st->queue = (int*)malloc((maxlen + 1) * sizeof(int));
        st->queuemax = maxlen + 1;
        st->bottom = 0;
        st->top = 0;
        st->queuenum = 0;
    }
}
  • queue_init 函数用于初始化队列:
    • 如果队列指针 queue 为空,分配 maxlen + 1 个整数的内存空间。
    • queuemax 设置为 maxlen + 1,这表示队列的最大长度。
    • topbottom 都初始化为 0,表示队列为空。

3. 入队操作

int queue_push(stQueue* st, int data) {
    int ret = -1;
    if ((st->bottom + 1) % (st->queuemax) == st->top) {
        printf("full\n");
    } else {
        st->queue[st->bottom] = data;
        st->bottom = (st->bottom + 1) % st->queuemax;
        ret = 0;
    }
    return ret;
}
  • queue_push 函数用于将元素 data 入队:
    • 通过检查 (st->bottom + 1) % st->queuemax == st->top 来判断队列是否已满。如果满了,打印 "full"。
    • 如果队列未满,将 data 存储到 queue[bottom],然后将 bottom 的索引加一,并取模以实现循环队列。
    • 如果操作成功,返回 0;否则返回 -1

4. 出队操作

int queue_pop(stQueue* st) {
    int ret = -1;
    if (st->bottom == st->top) {
        printf("empty\n");
    } else {
        printf("%d\n", st->queue[st->top]);
        st->top = (st->top + 1) % st->queuemax;
        ret = 0;
    }
    return ret;
}
  • queue_pop 函数用于将队列头部元素出队:
    • 通过检查 bottom == top 来判断队列是否为空。如果为空,打印 "empty"。
    • 如果队列不为空,打印队列头部元素 queue[top],然后将 top 的索引加一,并取模以实现循环队列。
    • 如果操作成功,返回 0;否则返回 -1

5. 查看队列头部元素

int queue_front(stQueue* st) {
    int ret = -1;
    if (st->bottom == st->top) {
        printf("empty\n");
    } else {
        printf("%d\n", st->queue[st->top]);
        ret = 0;
    }
    return ret;
}
  • queue_front 函数用于查看队列的头部元素:
    • queue_pop 类似,通过检查 bottom == top 来判断队列是否为空。
    • 如果队列不为空,打印队列头部元素 queue[top],但不修改 top 的值。
    • 如果操作成功,返回 0;否则返回 -1

6. 主函数

int main() {
    char op[100] = {0};
    unsigned int n, q = 0;
    stQueue stMyqueue = {0};
    scanf("%d %d", &n, &q);
    queue_init(&stMyqueue, n);
    for (unsigned int i = 0; i <= q; i++) {
        fgets(op, sizeof(op), stdin);
        if (strstr(op, "push")) {
            queue_push(&stMyqueue, atoi(op + 5));
        } else if (strstr(op, "pop")) {
            queue_pop(&stMyqueue);
        } else if (strstr(op, "front")) {
            queue_front(&stMyqueue);
        }
    }
    return 0;
}

main 函数控制程序的整体流程:

  • 读取两个整数 nq,其中 n 是队列的最大长度,q 是操作的数量。
  • 初始化队列 stMyqueue
  • 循环读取 q 次操作,根据操作类型调用相应的函数(pushpopfront)。
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Objective-C语言中可以使用NSArray或NSMutableArray来实现队列,但是它们是动态数组,插入和删除操作效率较低。如果需要实现一个高效的队列,可以使用循环队列循环队列是一种特殊的队列,它的队尾指针可以指向队头位置,形成一个环形结构。这样可以充分利用数组空间,提高队列的效率。 下面是Objective-C实现一个循环队列的示例代码: ``` @interface CircularQueue : NSObject @property(nonatomic, assign) NSInteger head; // 队头指针 @property(nonatomic, assign) NSInteger tail; // 队尾指针 @property(nonatomic, assign) NSInteger size; // 队列大小 @property(nonatomic, strong) NSMutableArray *queueArray; // 队列数组 - (instancetype)initWithSize:(NSInteger)size; // 初始化方法 - (BOOL)enqueue:(id)obj; // 入队方法 - (id)dequeue; // 出队方法 - (BOOL)isEmpty; // 判断队列是否为空 - (BOOL)isFull; // 判断队列是否已满 @end @implementation CircularQueue - (instancetype)initWithSize:(NSInteger)size { if (self = [super init]) { self.head = 0; self.tail = 0; self.size = size; self.queueArray = [NSMutableArray arrayWithCapacity:size]; for (NSInteger i = 0; i < size; i++) { [self.queueArray addObject:[NSNull null]]; } } return self; } - (BOOL)enqueue:(id)obj { if ([self isFull]) { return NO; } self.queueArray[self.tail] = obj; self.tail = (self.tail + 1) % self.size; return YES; } - (id)dequeue { if ([self isEmpty]) { return nil; } id obj = self.queueArray[self.head]; self.queueArray[self.head] = [NSNull null]; self.head = (self.head + 1) % self.size; return obj; } - (BOOL)isEmpty { return self.head == self.tail && self.queueArray[self.head] == [NSNull null]; } - (BOOL)isFull { return self.head == self.tail && self.queueArray[self.head] != [NSNull null]; } @end ``` 在上面的代码中,我们使用一个NSMutableArray来保存队列元素,使用head和tail两个指针来指示队头和队尾位置。enqueue方法用于入队操作,dequeue方法用于出队操作,isEmpty方法和isFull方法分别用于判断队列是否为空和已满。注意,在enqueue和dequeue方法中,我们使用取模运算来实现循环指针的功能。 使用循环队列可以有效提高队列的效率,特别是在需要频繁插入和删除元素的场景下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值